read_card
CaesarBao 5 months ago
parent 3f7054e31f
commit 60a43a6828

@ -28,8 +28,8 @@ namespace SlnMesnac.Business.@base
private ILogger<BaseTaskInfoBusiness> _logger;
private IAirportTaskService _Taskservice;
private IAGVStateService _AGVStateService;
private AirPorthttpClient _airPorthttpClient;
public BaseTaskInfoBusiness(ILogger<BaseTaskInfoBusiness> logger, IAirportTaskService Taskservice, IAGVStateService agvService, TcpServer tcpServer, AirPorthttpClient airPorthttpClient)
private MeshttpClient _airPorthttpClient;
public BaseTaskInfoBusiness(ILogger<BaseTaskInfoBusiness> logger, IAirportTaskService Taskservice, IAGVStateService agvService, TcpServer tcpServer, MeshttpClient airPorthttpClient)
{
_logger = logger;
_tcpServer = tcpServer;
@ -107,7 +107,7 @@ namespace SlnMesnac.Business.@base
}
}
public static BaseTaskInfoBusiness GetInstance(ILogger<BaseTaskInfoBusiness> logger, IAirportTaskService Taskservice, IAGVStateService agvService, TcpServer tcpServer, AirPorthttpClient airPorthttpClient)
public static BaseTaskInfoBusiness GetInstance(ILogger<BaseTaskInfoBusiness> logger, IAirportTaskService Taskservice, IAGVStateService agvService, TcpServer tcpServer, MeshttpClient airPorthttpClient)
{
if (instance == null)
{

@ -1,9 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
using Models;
using Serilog;
using SlnMesnac.Config;
using SlnMesnac.Plc;
using SlnMesnac.Rfid;
using SlnMesnac.Rfid.Factory;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
@ -38,42 +40,51 @@ namespace SlnMesnac.Extensions
{
services.AddSingleton<List<RfidAbsractFactory>>(x =>
{
ISqlSugarClient sqlSugarClient = x.GetRequiredService<ISqlSugarClient>();
AppConfig appConfig = x.GetService<AppConfig>();
List <RfidAbsractFactory> absractFactories = new List<RfidAbsractFactory>();
List<Base_device_info> baseRfidInfos = sqlSugarClient.Queryable<Base_device_info>().Where(x=>x.Collectid == appConfig.StationCode).ToList();
List<Base_sensor_info> sensor_Infos = sqlSugarClient.Queryable<Base_sensor_info>().Where(x => x.Deleteflag == 0).ToList();
List<RfidAbsractFactory> absractFactories = new List<RfidAbsractFactory>();
try
{
if (appConfig.rfidConfig != null)
foreach (var item in baseRfidInfos)
{
foreach (var item in appConfig.rfidConfig)
if (item.Deleteflag == 0)
{
if (item.isFlage)
int colonIndex = item.Connectstr.IndexOf(":");
string IP = colonIndex != -1 ? item.Connectstr.Substring(0, colonIndex) : item.Connectstr;
string Port = colonIndex != -1 ? item.Connectstr.Substring(colonIndex + 1) : item.Connectstr;
RfidAbsractFactory _rfid = x.GetService<RflyFactory>();
_rfid.ip = IP;
_rfid.port = int.Parse(Port);
_rfid.ConfigKey = sensor_Infos.Find(x => x.Deviceid == item.Deviceid).Combineid;
_rfid.FilterData = sensor_Infos.Find(x => x.Deviceid == item.Deviceid).Mapid;
//bool connectResult = _rfid.Connect(IP, int.Parse(Port));
bool connectResult = false;
if (connectResult)
{
RfidAbsractFactory _rfid = x.GetService<RflyFactory>();
bool connectResult = _rfid.Connect(item.equipIp, item.equipPort);
if (connectResult)
{
Log.Information($"RFID{item.equipIp}:{item.equipPort};连接成功,时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
_rfid.ConfigKey = item.equipKey;
//Log.Information($"RFID{item.Connectstr};连接成功,时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
//_rfid.ConfigKey = item.equipKey;
if (absractFactories.Contains(_rfid))
{
absractFactories.Remove(_rfid);
}
absractFactories.Add(_rfid);
}
else
if (absractFactories.Contains(_rfid))
{
Log.Information($"RFID{item.equipIp}:{item.equipPort};连接失败,时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
absractFactories.Remove(_rfid);
}
absractFactories.Add(_rfid);
}
else
{
//Log.Information($"RFID{item.Connectstr};连接失败,时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
if (absractFactories.Contains(_rfid))
{
absractFactories.Remove(_rfid);
}
absractFactories.Add(_rfid);
}
}
}
else
{
Log.Error("RFID配置信息为空");
}
}
catch (Exception e)
{

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.Model.domain
{
public class ApiResponse<T>
{
/// <summary>
/// 状态码(如 200 成功400 失败500 错误)
/// </summary>
public int Code { get; set; }
/// <summary>
/// 消息(如 "操作成功"、"参数错误"
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 返回数据
/// </summary>
public T Data { get; set; }
}
}

@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
namespace Models
{
/// <summary>
///
///</summary>
[SugarTable("base_device_info")]
public class Base_device_info
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="deviceid" ,IsPrimaryKey = true) ]
public string Deviceid { get; set; } = null!;
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="name" ) ]
public string? Name { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="connectstr" ) ]
public string? Connectstr { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="connectmode" ) ]
public decimal? Connectmode { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="devicetype" ) ]
public string? Devicetype { get; set; }
/// <summary>
/// 备 注:所属汇集软件ID
/// 默认值:
///</summary>
[SugarColumn(ColumnName="collectid" ) ]
public string? Collectid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="addr" ) ]
public string? Addr { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="mapid" ) ]
public string? Mapid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="recordtime" ) ]
public DateTime? Recordtime { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="deleteflag" ) ]
public int? Deleteflag { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="recordperson" ) ]
public int? Recordperson { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="objid" ,IsIdentity = true) ]
public int Objid { get; set; }
public string State = "未连接";
}
}

@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
namespace Models
{
/// <summary>
///
///</summary>
[SugarTable("base_sensor_info")]
public class Base_sensor_info
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="sensorid" ,IsPrimaryKey = true) ]
public string Sensorid { get; set; } = null!;
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="combineid" ) ]
public string Combineid { get; set; } = null!;
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="name" ) ]
public string? Name { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="sensorser" ) ]
public decimal? Sensorser { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="sensortypeid" ) ]
public decimal? Sensortypeid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="deviceid" ) ]
public string? Deviceid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="readinterval" ) ]
public decimal? Readinterval { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="multdata" ) ]
public decimal? Multdata { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="timedout" ) ]
public decimal? Timedout { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="returnimm" ) ]
public decimal? Returnimm { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="mapid" ) ]
public string? Mapid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="recordtime" ) ]
public DateTime? Recordtime { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="deleteflag" ) ]
public int? Deleteflag { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="recordperson" ) ]
public int? Recordperson { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="objid" ,IsIdentity = true) ]
public int Objid { get; set; }
/// <summary>
/// 备 注:是否调用适配器 1是 2否
/// 默认值:
///</summary>
[SugarColumn(ColumnName="CallAdapter" ) ]
public decimal? CallAdapter { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="CallCombineID" ) ]
public string? CallCombineID { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="mesid" ) ]
public string? Mesid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="DelayTime" ) ]
public string? DelayTime { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="ReadCounts" ) ]
public string? ReadCounts { get; set; }
}
}

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SlnMesnac.Model.domain
{
public class DeviceInfo
{
public string connectstr { get; set; }
public string combineid { get; set; }
public string addr { get; set; }
public string port { get; set; }
}
}

@ -0,0 +1,12 @@
namespace SlnMesnac.Model.domain
{
public class MesAlarmLightPara
{
public string EQUID { get; set; }
public string Sendtime { get; set; }
public string Code { get; set; }
public string msg { get; set; }
}
}

@ -0,0 +1,15 @@
namespace SlnMesnac.Model.domain
{
public class MesParaData
{
public MesParaData()
{
}
public string EQUID { get; set; }
public string EPCID { get; set; }
public string READSTATUS { get; set; }
public string ERRORMSG { get; set; }
public string READTIME { get; set; }
}
}

@ -0,0 +1,10 @@
namespace SlnMesnac.Model.domain
{
public class MesReadPara
{
public string EQUID { get; set; }
public string requesttime { get; set; }
}
}

@ -0,0 +1,10 @@
namespace SlnMesnac.Model.domain
{
public class MesReadRespon
{
public string EPCID { get; set; }
public string Respontime { get; set; }
}
}

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.Model.domain
{
public class RFIDDeviceApiResponse<T>
{
/// <summary>
/// 状态码(如 200 成功400 失败500 错误)
/// </summary>
public int Code { get; set; }
/// <summary>
/// 消息(如 "操作成功"、"参数错误"
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 返回数据
/// </summary>
public List<T> Data { get; set; }
}
}

@ -0,0 +1,10 @@
namespace SlnMesnac.Model.domain
{
public class RFIDDeviceInfo
{
public string IPAddress { get; set; }
public string EQUID { get; set; }
public string position { get; set; }
public string ApiPort { get; set; }
}
}

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
namespace Models
{
/// <summary>
///
///</summary>
[SugarTable("real_mesdata")]
public class Real_mesdata
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="combineid" ) ]
public string? Combineid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="tm" ) ]
public DateTime? Tm { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="data" ) ]
public string? Data { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="response" ) ]
public string? Response { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="reportmode" ) ]
public decimal? Reportmode { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="edittime" ) ]
public DateTime? Edittime { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="deleteflag" ) ]
public int? Deleteflag { get; set; }
}
}

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SqlSugar;
namespace Models
{
/// <summary>
///
///</summary>
[SugarTable("real_workdata")]
public class Real_workdata
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="combineid" ) ]
public string? Combineid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="tm" ) ]
public DateTime? Tm { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="data" ) ]
public string? Data { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="reportmode" ) ]
public decimal? Reportmode { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="edittime" ) ]
public DateTime? Edittime { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
[SugarColumn(ColumnName="deleteflag" ) ]
public int? Deleteflag { get; set; }
}
}

@ -0,0 +1,15 @@
using Models;
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service.@base;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.Repository.service
{
public interface IReal_mesdataService : IBaseService<Real_mesdata>
{
Task<bool> AddAsync(Real_mesdata record);
}
}

@ -0,0 +1,19 @@
using Models;
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service.@base;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.Repository.service
{
public interface IReal_workdataService : IBaseService<Real_workdata>
{
Task<bool> AddAsync(Real_workdata record);
List<DeviceInfo> GetDeviceInfos();
string GetPort(string collectid);
}
}

@ -0,0 +1,26 @@
using ATC_MaterialBind.Entity;
using Models;
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service.@base;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace SlnMesnac.Repository.service.Impl
{
public class Real_mesdataServiceImpl : BaseServiceImpl<Real_mesdata>, IReal_mesdataService
{
public Real_mesdataServiceImpl(Repository<Real_mesdata> repository):base(repository)
{
}
public async Task<bool> AddAsync(Real_mesdata record)
{
var newDb = _rep.CopyNew();
bool result = await newDb.InsertAsync(record);
return result;
}
}
}

@ -0,0 +1,56 @@
using ATC_MaterialBind.Entity;
using Models;
using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service.@base;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace SlnMesnac.Repository.service.Impl
{
public class Real_workdataServiceImpl : BaseServiceImpl<Real_workdata>, IReal_workdataService
{
public Real_workdataServiceImpl(Repository<Real_workdata> repository):base(repository)
{
}
public async Task<bool> AddAsync(Real_workdata record)
{
var newDb = _rep.CopyNew();
bool result = await newDb.InsertAsync(record);
return result;
}
public List<DeviceInfo> GetDeviceInfos()
{
List<DeviceInfo> taskInfos = null;
try
{
String sql = "select t1.connectstr, t2.combineid,t1.addr,t3.port from base_device_info t1 left join [dbo].[base_sensor_info] t2 on t1.deviceid = t2.deviceid left join [dbo].[base_collect_info] t3 on t1.collectid = t3.collectId where t1.deleteflag != 1 ";
taskInfos = base._rep.AsTenant().GetConnection("mes").Ado.SqlQuery<DeviceInfo>(sql);
}
catch (Exception ex)
{
}
return taskInfos;
}
public string GetPort(string collectid)
{
string port = "9880";
try
{
List<DeviceInfo> device = new List<DeviceInfo>();
String sql = " SELECT [port] FROM [WLDB].[dbo].[base_collect_info] where deleteflag != 1 and collectId = "+ collectid;
device = base._rep.AsTenant().GetConnection("mes").Ado.SqlQuery<DeviceInfo>(sql);
return device[0].port;
}
catch (Exception ex)
{
return port;
}
}
}
}

@ -0,0 +1,271 @@

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Models;
using Nancy;
using SlnMesnac.Model.AirportApiEntity;
using SlnMesnac.Model.domain;
using SlnMesnac.Model.dto;
using SlnMesnac.Repository.service;
using SlnMesnac.Repository.service.@base;
using SlnMesnac.Rfid;
using SlnMesnac.Rfid.Factory;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TouchSocket.Rpc;
using TouchSocket.WebApi;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* T14-GEN3-7895
* SlnMesnac.TouchSocket
* 649766cc-308e-4bf3-8d69-dea48ec40642
*
* WenJY
*
* 2024-09-04 10:51:54
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.TouchSocket
{
public class ApiServer: RpcServer
{
private ILogger<ApiServer> _logger;
private List<RfidAbsractFactory> rfidAbsractFactory;
private List<Base_sensor_info> base_Sensor_Infos;
public static Action<string> _RefreshLogMessageAction;
public static Action<string, string> RefreshStateEvent;
private IReal_mesdataService _real_MesdataService;
private IReal_workdataService _real_WorkdataService;
public ApiServer(ILogger<ApiServer> logger, List<RfidAbsractFactory> rfidAbsractFactory, IReal_mesdataService real_MesdataService, IReal_workdataService real_WorkdataService)
{
_logger = logger;
this.rfidAbsractFactory = rfidAbsractFactory;
_real_MesdataService = real_MesdataService;
_real_WorkdataService = real_WorkdataService;
}
/// <summary>
/// 测试
/// </summary>
/// <param name="mesParaData"></param>
/// <returns></returns>
[WebApi(Method = HttpMethodType.POST)]
public async Task<ApiResponse<MesParaData>> autoread()
{
return new ApiResponse<MesParaData>
{
Code = 200,
Data = null,
Msg = "sucess",
};
}
/// <summary>
/// 查询设备信息
/// </summary>
/// <param name="Requesttime"></param>
/// <returns></returns>
[WebApi(Method = HttpMethodType.POST)]
public async Task<RFIDDeviceApiResponse<DeviceInfo>> basedata(string Requesttime)
{
List<DeviceInfo> rFIDDeviceInfos = _real_WorkdataService.GetDeviceInfos();
return new RFIDDeviceApiResponse<DeviceInfo>
{
Code = 200,
Data = rFIDDeviceInfos,
Msg = "sucess",
};
}
private bool iFlag = false;
/// <summary>
/// MES主动请求读取标签
/// </summary>
/// <param name="EQUID"></param>
/// <param name="requesttime"></param>
/// <returns></returns>
[WebApi(Method = HttpMethodType.POST)]
public async Task<ApiResponse<MesReadRespon>> read(MesReadPara mesReadPara)
{
ApiResponse<MesReadRespon> response = new ApiResponse<MesReadRespon>();
int code = 400;
string Msg = "error";
MesReadRespon mesReadRespon = new MesReadRespon();
try
{
if (iFlag)
{
response = new ApiResponse<MesReadRespon>()
{
Code = code,
Data = mesReadRespon,
Msg = Msg,
};
return response;
}
// 设置标志位为 true表示方法正在执行
iFlag = true;
_RefreshLogMessageAction?.Invoke("接收MES主动读取指令" + JsonSerializer.Serialize(mesReadPara));
_logger.LogInformation("接收MES主动读取指令{0}", JsonSerializer.Serialize(mesReadPara));
string FilterData = rfidAbsractFactory.Find(x => x.ConfigKey == mesReadPara.EQUID).FilterData;
List<TagInfo> rfid = await rfidAbsractFactory.Find(x => x.ConfigKey == mesReadPara.EQUID).GetRFIDAsync();
rfid = rfid.Where((x, i) => rfid.FindIndex(z => z.EPCstring == x.EPCstring) == i).ToList();
//新增工位过滤
if (!string.IsNullOrEmpty(FilterData))
{
rfid = FilterByEPCString(rfid, FilterData);
}
if (rfid != null && rfid.Count > 0)
{
if (rfid.Count > 1)
{
if (rfid != null && rfid.Any())
{
mesReadRespon.EPCID = string.Join(",", rfid.Select(item => item.EPCstring));
//mesReadRespon.EPCID = "MORE";
Msg = "multiple EPC";
}
}
else
{
mesReadRespon.EPCID = rfid[0].EPCstring;
code = 200;
Msg = "sucess";
}
mesReadRespon.Respontime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
Real_workdata real_Workdata = new Real_workdata()
{
Combineid = mesReadPara.EQUID.ToString(),
Data = mesReadRespon.EPCID,
Tm = DateTime.Now,
Deleteflag = 0,
Reportmode = 0,
Edittime = DateTime.Now,
};
await _real_WorkdataService.AddAsync(real_Workdata);
}
else
{
Msg = "nodata";
}
response = new ApiResponse<MesReadRespon>()
{
Code = code,
Data = mesReadRespon,
Msg = Msg,
};
_RefreshLogMessageAction?.Invoke("发送MES主动读取指令" + JsonSerializer.Serialize(response));
_logger.LogInformation("发送MES主动读取指令{0}", JsonSerializer.Serialize(response));
Real_mesdata real_Mesdata = new Real_mesdata()
{
Combineid = mesReadPara.EQUID.ToString(),
Data = JsonSerializer.Serialize(mesReadPara),
Response = JsonSerializer.Serialize(response),
Reportmode = 0,
Edittime = DateTime.Now,
Tm = DateTime.Now,
Deleteflag = 0,
};
//InsertRealMesData(mesReadPara.EQUID.ToString(), JsonSerializer.Serialize(mesReadPara), JsonSerializer.Serialize(response), 0);
RefreshStateEvent?.Invoke(mesReadPara.EQUID, mesReadRespon.EPCID);
await _real_MesdataService.AddAsync(real_Mesdata);
return response;
}
catch (Exception ex)
{
_logger.LogInformation("read接口异常" + ex.ToString());
return response;
}
finally
{
iFlag = false;
}
}
private static List<TagInfo> FilterByEPCString(List<TagInfo> tagList, string searchText)
{
return tagList
.Where(tag => tag.EPCstring != null && tag.EPCstring.Contains(searchText))
.ToList();
}
/// <summary>
/// MES主动回复处理结果控制报警灯
/// </summary>
/// <param name="EQUID"></param>
/// <param name="requesttime"></param>
/// <returns></returns>
[WebApi(Method = HttpMethodType.POST)]
public async Task<ApiResponse<MesParaData>> revresult(MesAlarmLightPara mesAlarmLightPara)
{
ApiResponse<MesParaData> response = new ApiResponse<MesParaData>();
_RefreshLogMessageAction?.Invoke("接收MES控制报警灯指令" + JsonSerializer.Serialize(mesAlarmLightPara));
_logger.LogInformation("接收MES控制报警灯指令{0}", JsonSerializer.Serialize(mesAlarmLightPara));
if (mesAlarmLightPara.Code == "0")
{
mesAlarmLightPara.Code = "2";
}
else if (mesAlarmLightPara.Code == "1")
{
mesAlarmLightPara.Code = "3";
}
else
{
mesAlarmLightPara.Code = "1";
}
await rfidAbsractFactory.Find(x => x.ConfigKey == mesAlarmLightPara.EQUID).WriteAlarmLight(int.Parse(mesAlarmLightPara.Code),10000);
//m_EquipClient.WriteAlarmLight(mesAlarmLightPara.EQUID, mesAlarmLightPara.Code);
response = new ApiResponse<MesParaData>()
{
Code = 200,
Data = null,
Msg = "sucess",
};
_RefreshLogMessageAction?.Invoke("发送MES控制报警灯指令" + JsonSerializer.Serialize(response));
_logger.LogInformation("发送MES控制报警灯指令{0}", JsonSerializer.Serialize(response));
Real_mesdata real_Mesdata = new Real_mesdata()
{
Combineid = mesAlarmLightPara.EQUID.ToString(),
Data = JsonSerializer.Serialize(mesAlarmLightPara),
Response = JsonSerializer.Serialize(response),
Reportmode = 1,
Edittime = DateTime.Now,
Tm = DateTime.Now,
Deleteflag = 0,
};
await _real_MesdataService.AddAsync(real_Mesdata);
//InsertRealMesData(mesAlarmLightPara.EQUID.ToString(), JsonSerializer.Serialize(mesAlarmLightPara), JsonSerializer.Serialize(response), 1);
return response;
}
}
}

@ -1,14 +1,20 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Models;
using SlnMesnac.Common;
using SlnMesnac.Model.domain;
using SlnMesnac.Model.dto;
using SlnMesnac.Repository.service;
using SlnMesnac.Rfid.Dto;
using SlnMesnac.Rfid.Enum;
using SlnMesnac.TouchSocket;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Sockets;
@ -41,11 +47,15 @@ namespace SlnMesnac.Rfid.Factory
private ILogger<RflyFactory> _logger;
private readonly TcpClient _tcpClient = new TcpClient();
private readonly StringChange _stringChange;
private string m_strIP;
private string m_deviceID;
private MeshttpClient _meshttpClient;
public RflyFactory(ILogger<RflyFactory> logger,StringChange stringChange)
public RflyFactory(ILogger<RflyFactory> logger,StringChange stringChange, MeshttpClient meshttpClient)
{
_logger = logger;
_stringChange = stringChange;
_meshttpClient = meshttpClient;
}
/// <summary>
@ -65,10 +75,62 @@ namespace SlnMesnac.Rfid.Factory
}
catch (Exception e)
{
throw new InvalidOperationException($"设备连接异常:{e.Message}");
return false;
//throw new InvalidOperationException($"设备连接异常:{e.Message}");
}
}
/// <summary>
/// 异步建立连接
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public override async Task<bool> ConnectAsync(string ip, int port,string deviceid)
{
try
{
m_deviceID = deviceid;
m_strIP = ip;
_tcpClient.Setup(new TouchSocketConfig().SetRemoteIPHost($"{ip}:{port}"));
await _tcpClient.ConnectAsync(1500);
_tcpClient.Received = (client, e) =>
{
//从客户端收到信息
var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意数据长度是byteBlock.Len
byte[] receivedBuffer = new byte[e.ByteBlock.Len];
Array.Copy(e.ByteBlock.Buffer, 0, receivedBuffer, 0, e.ByteBlock.Len);
byte[] resultBuffer = PareReceiveBufferData(receivedBuffer, receivedBuffer.Length);
List<TagInfo> tagInfoList = Device_DealTagInfoList(resultBuffer);
string info = "";
if (tagInfoList!=null && tagInfoList.Count > 0)
{
tagInfoList = tagInfoList.Where((x, i) => tagInfoList.FindIndex(z => z.EPCstring == x.EPCstring) == i).ToList();
info = string.Join(",", tagInfoList.Select(item => item.EPCstring));
}
else
{
info = "Nodata";
}
MesParaData mesParaData = new MesParaData()
{
EQUID = deviceid,
EPCID = info,
READSTATUS = info == "NoData" ? "1" : "0",
READTIME = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
};
_meshttpClient.autoread(mesParaData);
//ReceivedClientBufferEvent?.Invoke(receivedBuffer);
return EasyTask.CompletedTask;
};
return true;
}
catch (Exception e)
{
return false;
}
}
/// <summary>
/// 按时间段盘点
/// </summary>
@ -119,6 +181,301 @@ namespace SlnMesnac.Rfid.Factory
throw new InvalidOperationException($"按时间段盘点异常:{e.Message}");
}
}
/// <summary>
/// 异步按时间段盘点
/// </summary>
/// <param name="timeout"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public override async Task<List<TagInfo>> GetRFIDAsync(int timeout = 1500)
{
List<TagInfo> tagInfoList = new List<TagInfo>();
byte[] u16byte = new byte[2];
byte[] bCRC = new byte[4];
try
{
#region 指令封装
MessagePack pMessagePack = new MessagePack();
pMessagePack.m_pData = new byte[8];
pMessagePack.m_pData[0] = 0xAA;
pMessagePack.m_pData[1] = 0x55;
pMessagePack.m_pData[2] = 0x02;
pMessagePack.m_pData[3] = 0x02;
//1s
pMessagePack.m_pData[4] = 0x03;
pMessagePack.m_pData[5] = 0xE8;
//2s
//pMessagePack.m_pData[4] = 0x07;
//pMessagePack.m_pData[5] = 0xD0;
//3s
//pMessagePack.m_pData[4] = 0x0B;
//pMessagePack.m_pData[5] = 0xA0;
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 4);
pMessagePack.m_pData[6] = _stringChange.CalculateVerify(bCRC, bCRC.Length);
pMessagePack.m_pData[7] = 0x0D;
#endregion 指令封装
var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions()
{
FilterFunc = response =>
{
// 检查响应数据是否符合预期
if (response.Data != null && response.Data.Length > 0)
{
// 可以根据实际情况添加更多的检查逻辑
return true;
}
return false;
}
});
byte[] reciveBuffer = await waitClient.SendThenReturnAsync(pMessagePack.m_pData, timeout);
_logger.LogInformation($"{m_deviceID}发送读取指令{_stringChange.bytesToHexStr(pMessagePack.m_pData,pMessagePack.m_pData.Length)}");
byte[] resultBuffer = PareReceiveBufferData(reciveBuffer, reciveBuffer.Length);
_logger.LogInformation($"{m_deviceID}接收读取指令{_stringChange.bytesToHexStr(resultBuffer,resultBuffer.Length)}");
tagInfoList = Device_DealTagInfoList(resultBuffer);
return tagInfoList;
}
catch (Exception e)
{
return tagInfoList;
//throw new InvalidOperationException($"{m_strIP}按时间段盘点异常:{e.Message}");
}
}
/// <summary>
/// 设置GPIO
/// </summary>
/// <param name="port"></param>
/// <param name="Timedout"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public override async Task<bool> WriteAlarmLight(int port, UInt16 Timedout)
{
byte[] u16byte = new byte[2];
byte[] bCRC = new byte[6];
try
{
#region 指令封装
MessagePack pMessagePack = new MessagePack();
pMessagePack.m_pData = new byte[10];
pMessagePack.m_pData[0] = 0xAA;
pMessagePack.m_pData[1] = 0x55;
pMessagePack.m_pData[2] = 0x04;
pMessagePack.m_pData[3] = 0x51;
pMessagePack.m_pData[4] = (byte)port;
pMessagePack.m_pData[5] = 0x00;
u16byte = BitConverter.GetBytes(Timedout); //超时时间
u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前
Array.Copy(u16byte, 0, pMessagePack.m_pData, 6, 2);
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 6);
pMessagePack.m_pData[8] = _stringChange.CalculateVerify(bCRC, bCRC.Length);
pMessagePack.m_pData[9] = 0x0D;
#endregion 指令封装
var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions()
{
FilterFunc = response =>
{
// 检查响应数据是否符合预期
if (response.Data != null && response.Data.Length > 0)
{
// 可以根据实际情况添加更多的检查逻辑
return true;
}
return false;
}
});
byte[] reciveBuffer = await waitClient.SendThenReturnAsync(pMessagePack.m_pData, 2000);
//byte[] resultBuffer = PareReceiveBufferData(reciveBuffer, reciveBuffer.Length);
if (reciveBuffer[3] == 0x51)
{
return true;
}
return false;
}
catch (Exception e)
{
throw new InvalidOperationException($"{m_strIP}设置GPIO异常{e.Message}");
}
}
/// <summary>
/// 设置功率
/// </summary>
/// <param name="iDbi"></param>
/// <returns></returns>
public override async Task<bool> Set_Rf(int iDbi)
{
byte[] u16byte = new byte[2];
byte[] bCRC = new byte[22];
try
{
#region 指令封装
iDbi = iDbi * 100;
MessagePack pMessagePack = new MessagePack();
pMessagePack.m_pData = new byte[26];
pMessagePack.m_pData[0] = 0xAA;
pMessagePack.m_pData[1] = 0x55;
pMessagePack.m_pData[2] = 0x14;
pMessagePack.m_pData[3] = 0x42;
pMessagePack.m_pData[4] = 0x01;
u16byte = BitConverter.GetBytes(iDbi); //功率
u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前
Array.Copy(u16byte, 0, pMessagePack.m_pData, 5, 2);
u16byte = BitConverter.GetBytes(iDbi); //功率
u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前
Array.Copy(u16byte, 0, pMessagePack.m_pData, 7, 2);
pMessagePack.m_pData[9] = 0x02;
u16byte = BitConverter.GetBytes(iDbi); //功率
u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前
Array.Copy(u16byte, 0, pMessagePack.m_pData, 10, 2);
u16byte = BitConverter.GetBytes(iDbi); //功率
u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前
Array.Copy(u16byte, 0, pMessagePack.m_pData, 12, 2);
pMessagePack.m_pData[14] = 0x03;
u16byte = BitConverter.GetBytes(iDbi); //功率
u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前
Array.Copy(u16byte, 0, pMessagePack.m_pData, 15, 2);
u16byte = BitConverter.GetBytes(iDbi); //功率
u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前
Array.Copy(u16byte, 0, pMessagePack.m_pData, 17, 2);
pMessagePack.m_pData[19] = 0x04;
u16byte = BitConverter.GetBytes(iDbi); //功率
u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前
Array.Copy(u16byte, 0, pMessagePack.m_pData, 20, 2);
u16byte = BitConverter.GetBytes(iDbi); //功率
u16byte = _stringChange.Swap16Bytes(u16byte); //协议里为大端在前
Array.Copy(u16byte, 0, pMessagePack.m_pData, 22, 2);
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 22);
pMessagePack.m_pData[24] = _stringChange.CalculateVerify(bCRC, bCRC.Length);
pMessagePack.m_pData[25] = 0x0D;
#endregion 指令封装
var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions()
{
FilterFunc = response =>
{
// 检查响应数据是否符合预期
if (response.Data != null && response.Data.Length > 0)
{
// 可以根据实际情况添加更多的检查逻辑
return true;
}
return false;
}
});
_logger.LogInformation($"{m_deviceID}发送修改功率指令{_stringChange.bytesToHexStr(pMessagePack.m_pData, pMessagePack.m_pData.Length)}");
byte[] reciveBuffer = await waitClient.SendThenReturnAsync(pMessagePack.m_pData, 2000);
_logger.LogInformation($"{m_deviceID}接收修改功率指令{_stringChange.bytesToHexStr(reciveBuffer, reciveBuffer.Length)}");
//byte[] resultBuffer = PareReceiveBufferData(reciveBuffer, reciveBuffer.Length);
if (reciveBuffer[3] == 0x42)
{
return true;
}
return false;
}
catch (Exception e)
{
return false;
//throw new InvalidOperationException($"{m_strIP}设置功率异常:{e.Message}");
}
}
public override async Task<int> Get_Rf()
{
int DB = 0;
byte[] u16byte = new byte[2];
byte[] bCRC = new byte[2];
try
{
#region 指令封装
MessagePack pMessagePack = new MessagePack();
pMessagePack.m_pData = new byte[6];
pMessagePack.m_pData[0] = 0xAA;
pMessagePack.m_pData[1] = 0x55;
pMessagePack.m_pData[2] = 0x00;
pMessagePack.m_pData[3] = 0x72;
Array.Copy(pMessagePack.m_pData, 2, bCRC, 0, 2);
pMessagePack.m_pData[4] = _stringChange.CalculateVerify(bCRC, bCRC.Length);
pMessagePack.m_pData[5] = 0x0D;
#endregion 指令封装
var waitClient = _tcpClient.CreateWaitingClient(new WaitingOptions()
{
FilterFunc = response =>
{
// 检查响应数据是否符合预期
if (response.Data != null && response.Data.Length > 0)
{
// 可以根据实际情况添加更多的检查逻辑
return true;
}
return false;
}
});
byte[] reciveBuffer = await waitClient.SendThenReturnAsync(pMessagePack.m_pData, 2000);
if (reciveBuffer[3] == 0x72)
{
byte[] bDB = new byte[2];
bDB[0] = reciveBuffer[6];
bDB[1] = reciveBuffer[7];
DB = Convert.ToInt32(_stringChange.bytesToHexStr(bDB, 2), 16) / 100;
return DB;
}
return DB;
}
catch (Exception e)
{
return DB;
//throw new InvalidOperationException($"{m_strIP}设置功率异常:{e.Message}");
}
}
public override bool GetOnlineStatus()
{
try
{
return _tcpClient.Online;
}
catch (Exception e)
{
return false;
}
}
public override void Close()
{
try
{
_tcpClient.SafeDispose();
}
catch (Exception ex)
{
throw;
}
}
#region 标签解析
@ -188,6 +545,18 @@ namespace SlnMesnac.Rfid.Factory
m_iPosition++;
enumRecvState = RecvState.WaitingForStus_State;
}
else if (buffer[i] == 0x42)
{
m_szFullMessage[m_iPosition] = buffer[i];
m_iPosition++;
enumRecvState = RecvState.WaitingForStus_State;
}
else if (buffer[i] == 0x72)
{
m_szFullMessage[m_iPosition] = buffer[i];
m_iPosition++;
enumRecvState = RecvState.WaitingForStus_State;
}
else if (buffer[i] == 0x90) // 如果是心跳BB DD 01 90 00 1F 8E 0D
{
m_szFullMessage[m_iPosition] = buffer[i];
@ -333,7 +702,7 @@ namespace SlnMesnac.Rfid.Factory
}
}
private Mutex mutauto = new Mutex();
//private Mutex mutauto = new Mutex();
/// <summary>
/// 解析函数
/// </summary>
@ -348,7 +717,7 @@ namespace SlnMesnac.Rfid.Factory
int m_readEPCDataLen = 0;
try
{
mutauto.WaitOne();
//mutauto.WaitOne();
int iFirstCountPos = 6; //第一次读取标签次数位置
int iFirstRSSIPos = 7; //第一次读取标签强度位置
int iFirstAnt = 8;
@ -358,7 +727,7 @@ namespace SlnMesnac.Rfid.Factory
int tempDataRSSI = 0;
UInt16 tempDataANT = 0;
int iBarcodeGroupCount = Convert.ToInt32(AutoDealReportData[5].ToString()); //标签组数
int iBarcodeLength = 16; //标签长度
int iBarcodeLength = 12; //标签长度
int iCommonSecondFlag = 0;
for (int j = 0; j < iBarcodeGroupCount; j++)
{
@ -367,8 +736,11 @@ namespace SlnMesnac.Rfid.Factory
Array.Clear(tempPCByte, 0, 2);
Array.Copy(AutoDealReportData, iFirstPC, tempPCByte, 0, 2);
int pc = Convert.ToInt32(tempPCByte[0].ToString("X"));
int epcLength = EPCLengthByPC(pc);
//int pc = Convert.ToInt32(tempPCByte[0].ToString("X"));
//PC转二进制取前五位转十进制
int epcLength = Convert.ToInt32(Convert.ToString(Convert.ToInt64(tempPCByte[0].ToString("X"), 16), 2).PadLeft(8, '0').Substring(0, 5), 2) * 2;
//int epcLength = EPCLengthByPC(pc);
iBarcodeLength = epcLength;
byte[] tempDataByte = new byte[epcLength];
@ -396,15 +768,7 @@ namespace SlnMesnac.Rfid.Factory
tag.Count = tempDataCount;
tag.RSSI = tempDataRSSI;
tag.EPC = tempDataByte;
if (pc == 24)
{
tag.EPCstring = _stringChange.bytesToHexStr(tempDataByte, tempDataByte.Length).Substring(0, 7);
}
else
{
tag.EPCstring = Encoding.ASCII.GetString(tempDataByte);
}
tag.EPCstring = _stringChange.bytesToHexStr(tempDataByte, tempDataByte.Length).Substring(0,8);
tag.PC = tempPCByte;
tag.Antana = tempDataANT;
@ -417,12 +781,12 @@ namespace SlnMesnac.Rfid.Factory
iFirstPC = iFirstAnt + 1;
iFirstLeftBarcketPos = iFirstLeftBarcketPos + iBarcodeLength + 5;
_logger.LogInformation("----函数调用:Device_DealTagInfoList 第[" + (iCommonSecondFlag + 1) + "]次数据解析为:" + tag.EPCstring + ",读取标签次数:[" + tempDataCount + "],标签信号强度:[" + tempDataRSSI + "],天线号:[" + tempDataANT + "]");
_logger.LogInformation($"----{m_deviceID}函数调用:Device_DealTagInfoList 第[" + (iCommonSecondFlag + 1) + "]次数据解析为:" + tag.EPCstring + ",读取标签次数:[" + tempDataCount + "],标签信号强度:[" + tempDataRSSI + "],天线号:[" + tempDataANT + "]");
iCommonSecondFlag++;
if (iCommonSecondFlag == iBarcodeGroupCount)
{
mutauto.ReleaseMutex();
_logger.LogInformation("《《《返回标签数据!");
//mutauto.ReleaseMutex();
//_logger.LogInformation("《《《返回标签数据!");
return tagInfoList;
}
}
@ -430,7 +794,7 @@ namespace SlnMesnac.Rfid.Factory
}
catch (Exception ex)
{
mutauto.ReleaseMutex();
//mutauto.ReleaseMutex();
throw new InvalidOperationException($"Device_AutoDealContent 自动处理函数异常:{ex.Message}");
}
}
@ -478,6 +842,7 @@ namespace SlnMesnac.Rfid.Factory
return epcLength;
}
#endregion
}
}

@ -0,0 +1,111 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Nancy;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serilog;
using Serilog.Events;
using SlnMesnac.Config;
using SlnMesnac.Model.AirportApiEntity;
using SlnMesnac.Model.domain;
using SQLitePCL;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using TouchSocket.Rpc;
using TouchSocket.Sockets;
using TouchSocket.WebApi;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace SlnMesnac.TouchSocket
{
public class MeshttpClient
{
private readonly AppConfig _appConfig;
private readonly ILogger<MeshttpClient> _logger;
public static Action<string, string> RefreshStateEvent;
public static Action<string> _RefreshLogMessageAction;
public MeshttpClient(AppConfig appConfig, ILogger<MeshttpClient> logger)
{
_appConfig = appConfig;
_logger = logger;
}
public static WebApiClient MESHttpClient;
public WebApiClient CreateWebApiClient(string IpHost)
{
MESHttpClient = new WebApiClient();
try
{
_logger.LogInformation("正在连接:" + IpHost);
MESHttpClient.Connect(IpHost);
_logger.LogInformation(IpHost + "连接成功");
return MESHttpClient;
}
catch (Exception ex)
{
_logger.LogError("ERROR: " + ex.Message);
return null;
}
}
/// <summary>
/// 获取到的JToken类型转换为实体类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public T JTokenToEntity<T>(JToken value) where T : class
{
if (value == null)
{
return null;
}
string json = value.ToString();
if (string.IsNullOrEmpty(json))
{
return null;
}
T ResponseEntity;
ResponseEntity = JsonSerializer.Deserialize<T>(json);
return ResponseEntity;
}
/// <summary>
/// 主动上报
/// </summary>
/// <param name="requestValue"></param>
/// <returns></returns>
public ApiResponse<MesParaData> autoread(MesParaData requestValue)
{
try
{
if (MESHttpClient == null)
{
return null;
}
JToken responseValue = MESHttpClient.InvokeT<JToken>("POST:/autoread", null, requestValue);
//JToken responseValue = MESHttpClient.InvokeT<JToken>("POST:/ApiServer/autoread", null, requestValue);
_RefreshLogMessageAction?.Invoke("发送MES自动读取指令"+JsonSerializer.Serialize(requestValue));
_logger.LogInformation("发送MES自动读取指令{0}", JsonSerializer.Serialize(requestValue));
RefreshStateEvent?.Invoke(requestValue.EQUID,requestValue.EPCID);
return JTokenToEntity<ApiResponse<MesParaData>>(responseValue);
}
catch (Exception ex)
{
_logger.LogError("ERROR: " + ex.Message);
return new ApiResponse<MesParaData>();
}
}
}
}

@ -1,6 +1,7 @@
using System;
using SlnMesnac.Model.dto;
using System;
using System.Collections.Generic;
using SlnMesnac.Model.dto;
using System.Threading.Tasks;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
@ -31,9 +32,17 @@ namespace SlnMesnac.Rfid
/// </summary>
public abstract class RfidAbsractFactory
{
public string FilterData;
public string ip;
public int port;
public string ConfigKey { get; set; }
/// <summary>
/// 异步建立连接
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public abstract Task<bool> ConnectAsync(string ip, int port,string deviceid);
/// <summary>
/// 建立连接
/// </summary>
@ -41,12 +50,41 @@ namespace SlnMesnac.Rfid
/// <param name="port"></param>
/// <returns></returns>
public abstract bool Connect(string ip, int port);
/// <summary>
/// 获取设备在线状态
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
public abstract bool GetOnlineStatus();
public abstract void Close();
/// <summary>
/// 按时间段盘点
/// </summary>
/// <param name="timeout"></param>
/// <returns></returns>
public abstract List<TagInfo> TimePeriodRead(int timeout = 5000);
public abstract List<TagInfo> TimePeriodRead(int timeout = 3000);
/// <summary>
/// 使用--异步按时间段盘点
/// </summary>
/// <param name="timeout"></param>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public abstract Task<List<TagInfo>> GetRFIDAsync(int timeout = 1500);
/// <summary>
/// 设置GPIO
/// </summary>
/// <param name="port"></param>
/// <param name="Timedout"></param>
/// <returns></returns>
public abstract Task<bool> WriteAlarmLight(int port, UInt16 Timedout);
public abstract Task<bool> Set_Rf(int iDbi);
public abstract Task<int> Get_Rf();
}
}

@ -8,6 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\SlnMesnac.Common\SlnMesnac.Common.csproj" />
<ProjectReference Include="..\SlnMesnac.Model\SlnMesnac.Model.csproj" />
<ProjectReference Include="..\SlnMesnac.Repository\SlnMesnac.Repository.csproj" />
<ProjectReference Include="..\SlnMesnac.TouchSocket\SlnMesnac.TouchSocket.csproj" />
</ItemGroup>

@ -39,11 +39,13 @@ namespace SlnMesnac.TouchSocket
public static IApplicationBuilder UseTouchSocketExtensions(this IApplicationBuilder app)
{
var _server = app.ApplicationServices.GetService<TcpServer>();
var _httpclient = app.ApplicationServices.GetService<AirPorthttpClient>();
//var _server = app.ApplicationServices.GetService<TcpServer>();
var _httpclient = app.ApplicationServices.GetService<MeshttpClient>();
var _apiServer = app.ApplicationServices.GetService<WebApiServer>();
_apiServer.Init();
//_server.Init(6001);
//_httpclient.init();
_httpclient.CreateWebApiClient("172.16.0.106:9880");
//_httpclient.CreateWebApiClient("127.0.0.1:9880");
return app;
}
}

@ -1,4 +1,6 @@
using System;
using SlnMesnac.Config;
using SlnMesnac.Repository.service;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
@ -35,19 +37,24 @@ namespace SlnMesnac.TouchSocket
public class WebApiServer
{
private ApiServer _apiServer;
public WebApiServer(ApiServer apiServer)
private readonly AppConfig _appConfig;
private IReal_workdataService _real_WorkdataService;
public WebApiServer(ApiServer apiServer, AppConfig appConfig, IReal_workdataService real_WorkdataService)
{
_apiServer = apiServer;
_real_WorkdataService = real_WorkdataService;
_appConfig = appConfig;
}
public void Init()
{
try
{
//获取汇集软件服务端口号
string port = _real_WorkdataService.GetPort(_appConfig.StationCode);
var service = new HttpService();
service.Setup(new TouchSocketConfig()
.SetListenIPHosts(7789)
.SetListenIPHosts(int.Parse(port))
.ConfigureContainer(a =>
{
a.AddRpcStore(store =>

@ -1,167 +0,0 @@
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SlnMesnac.Config;
using SlnMesnac.Model.AirportApiEntity;
using SQLitePCL;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Text.Json;
using TouchSocket.Rpc;
using TouchSocket.Sockets;
using TouchSocket.WebApi;
using JsonSerializer = System.Text.Json.JsonSerializer;
using Serilog;
using Serilog.Events;
using Microsoft.Extensions.Logging;
namespace SlnMesnac.TouchSocket
{
public class AirPorthttpClient
{
private readonly AppConfig _appConfig;
private readonly ILogger<AirPorthttpClient> _logger;
public AirPorthttpClient(AppConfig appConfig, ILogger<AirPorthttpClient> logger)
{
_appConfig = appConfig;
_logger = logger;
}
public static WebApiClient AirportAGVClient;
private WebApiClient CreateWebApiClient(string IpHost)
{
var client = new WebApiClient();
try
{
_logger.LogInformation("正在连接:" + IpHost);
client.Connect(IpHost);
_logger.LogInformation(IpHost + "连接成功");
return client;
}
catch (Exception ex)
{
_logger.LogError("ERROR: " + ex.Message);
return null;
}
}
/// <summary>
/// 获取到的JToken类型转换为实体类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public T JTokenToEntity<T>(JToken value) where T : class
{
if (value == null)
{
return null;
}
string json = value.ToString();
if (string.IsNullOrEmpty(json))
{
return null;
}
T ResponseEntity;
ResponseEntity = JsonSerializer.Deserialize<T>(json);
return ResponseEntity;
}
/// <summary>
/// AGV下发任务请求
/// </summary>
/// <param name="requestValue"></param>
/// <returns></returns>
public AGVResponseEntity<ResponseAddTaskDataEntity> AGVAddTaskRequest(AGVRequestAddTaskEntity requestValue)
{
if (AirportAGVClient == null)
{
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("POST:/api/task/addTask", null, requestValue);
return JTokenToEntity<AGVResponseEntity<ResponseAddTaskDataEntity>>(responseValue);
}
/// <summary>
/// 取消/终止任务请求
/// </summary>
/// <param name="requestValue"></param>
/// <returns></returns>
public AGVResponseEntity<object> AGVOperationalTaskRequest(AGVRequestOperationalTaskEntity requestValue)
{
if (AirportAGVClient == null)
{
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("POST:/api/task/operationalTask", null, requestValue);
return JTokenToEntity<AGVResponseEntity<object>>(responseValue);
}
/// <summary>
/// 查询任务状态请求
/// </summary>
/// <param name="requestValue"></param>
/// <returns></returns>
public AGVResponseEntity<ResponseTaskStateDetailDataEntity> AGVGetTaskStateDetailRequest(AGVRequestTaskStateDetailEntity requestValue)
{
if (AirportAGVClient == null)
{
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("PUT:/api/task/getTaskStateDetail", null, requestValue);
return JTokenToEntity<AGVResponseEntity<ResponseTaskStateDetailDataEntity>>(responseValue);
}
/// <summary>
/// 获取所有AGV信息请求
/// </summary>
/// <returns></returns>
public AGVResponseEntity<List<ResponseRobotAtrributeDataEntity>> AGVAllStateRequest()
{
if (AirportAGVClient == null)
{
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/task/robot/getRobot", null);
return JTokenToEntity<AGVResponseEntity<List<ResponseRobotAtrributeDataEntity>>>(responseValue);
}
/// <summary>
/// 获取当前激活地图信息请求
/// </summary>
/// <returns></returns>
public AGVResponseEntity<ResponseActiveMapDataEntity> AGVMapActiveRequest()
{
if (AirportAGVClient == null)
{
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/v1.0.0/Maps/mapActive", null);
return JTokenToEntity<AGVResponseEntity<ResponseActiveMapDataEntity>>(responseValue);
}
/// <summary>
/// 获取当前地图所有位置点请求
/// </summary>
/// <param name="requestValue"></param>
/// <returns></returns>
public AGVResponseEntity<List<ResponseMapPositionDataEntity>> AGVMapPositionRequest(string requestValue)
{
if (AirportAGVClient == null)
{
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/v1.0.0/Positions?mapId={0}", null, requestValue);
return JTokenToEntity<AGVResponseEntity<List<ResponseMapPositionDataEntity>>>(responseValue);
}
}
}

@ -1,74 +0,0 @@
using SlnMesnac.Model.AirportApiEntity;
using System;
using System.Collections.Generic;
using System.Text;
using TouchSocket.Rpc;
using TouchSocket.WebApi;
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2024 WenJY
* CLR4.0.30319.42000
* T14-GEN3-7895
* SlnMesnac.TouchSocket
* 649766cc-308e-4bf3-8d69-dea48ec40642
*
* WenJY
*
* 2024-09-04 10:51:54
* V1.0.0
*
*
*--------------------------------------------------------------------
*
*
*
*
* V1.0.0
*--------------------------------------------------------------------*/
#endregion << 版 本 注 释 >>
namespace SlnMesnac.TouchSocket
{
public class ApiServer: RpcServer
{
public ApiServer()
{
}
public delegate void AGVArrivalStart(string message, AGVSingalEntity aGVArrivalSingalEntity);
/// <summary>
/// AGV到位信号刷新
/// </summary>
public event AGVArrivalStart AGVArrivalStartEvent;
/// <summary>
/// AGV到位信号接口
/// </summary>
/// <param name="messageHeader"></param>
/// <returns></returns>
[EnableCors("cors")]
[WebApi(HttpMethodType.POST)]
public object AGVSignal(string messageHeader, AGVSingalEntity aGVArrivalSingalEntity)
{
AGVArrivalStartEvent?.Invoke(messageHeader, aGVArrivalSingalEntity);
return "Success";
}
public void SubscribeToAGVArrivalEvent()
{
// 订阅 AGV 到位事件
AGVArrivalStartEvent += OnAGVArrival;
}
// 处理 AGV 到位事件的方法
public void OnAGVArrival(string message, AGVSingalEntity aGVArrivalSingalEntity)
{
Console.WriteLine($"收到AGV到位信号: {message}");
Console.WriteLine($"AGV编号: {aGVArrivalSingalEntity.AGVNo}, 到达位置: {aGVArrivalSingalEntity.DestinationNo}");
// 这里可以处理更多的业务逻辑,比如记录日志、更新系统状态等
}
}
}

@ -1,15 +1,16 @@
using Lierda.WPFHelper;
using Autofac.Extensions.DependencyInjection;
using Lierda.WPFHelper;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using SlnMesnac.Config;
using System;
using System.Windows;
using Autofac.Extensions.DependencyInjection;
using SlnMesnac.Plc;
using System.Collections.Generic;
using SlnMesnac.Rfid;
using System;
using System.Collections.Generic;
using System.Windows;
namespace SlnMesnac.WPF
{
@ -21,30 +22,60 @@ namespace SlnMesnac.WPF
private System.Threading.Mutex? mutex = null;
private LierdaCracker cracker = new LierdaCracker();
public static IServiceProvider? ServiceProvider = null;
private static IHost? host;
private AppConfig appConfig;
// Startup事件
protected override async void OnStartup(StartupEventArgs e)
{
try
{
bool ret;
mutex = new System.Threading.Mutex(true, System.Diagnostics.Process.GetCurrentProcess().ProcessName, out ret);
if (!ret)
{
MessageBox.Show("应用程序已开启,禁止重复运行");
Environment.Exit(0);
}
//mutex = new System.Threading.Mutex(true, System.Diagnostics.Process.GetCurrentProcess().ProcessName, out ret);
//if (!ret)
//{
// MessageBox.Show("应用程序已开启,禁止重复运行");
// Environment.Exit(0);
//}
cracker.Cracker(100); //设置GC回收间隔
base.OnStartup(e);
var host = CreateHostBuilder(e.Args).Build();//生成宿主。
//var host = CreateHostBuilder(e.Args).Build();//生成宿主。
ServiceProvider = host.Services;
//ServiceProvider = host.Services;
await host.StartAsync();
//await host.StartAsync();
var instanceId = GetInstanceId(e.Args);
// 创建完全独立的Host构建器
host = CreateHostBuilder(e.Args, instanceId).Build();
var appConfig = host.Services.GetService<AppConfig>();
// 预先验证服务
using (var scope = host.Services.CreateScope())
{
ServiceProvider = scope.ServiceProvider;
try
{
//serilogHelper = services.GetRequiredService<SerilogHelper>();
//serilogHelper.Info($"启动服务");
//var appConfig = services.GetRequiredService<AppConfig>();
appConfig = host.Services.GetService<AppConfig>();
// 强制设置实例ID到配置对象
SetInstanceSpecificConfiguration(appConfig, instanceId);
//serilogHelper.Info($"实例 {instanceId} 服务初始化完成");
Console.WriteLine($"实例 {instanceId} 服务初始化完成");
}
catch (Exception ex)
{
Console.WriteLine($"实例 {instanceId} 服务初始化失败: {ex.Message}");
//serilogHelper.Info($"详细错误: {ex}");
}
}
//await host.StartAsync();
var hostTask = host.RunAsync();
var logPath = $"{appConfig.logPath}/Logs/{DateTime.UtcNow:yyyy-MM-dd}/";
Log.Information($"系统初始化完成,日志存放路径:{appConfig.logPath}");
}
@ -56,7 +87,147 @@ namespace SlnMesnac.WPF
}
private static void SetInstanceSpecificConfiguration(AppConfig appConfig, string instanceId)
{
try
{
Console.WriteLine($"为实例 {instanceId} 设置特定配置...");
// 使用反射设置所有可能的配置属性
var configType = appConfig.GetType();
var properties = configType.GetProperties();
foreach (var property in properties)
{
if (property.CanWrite)
{
var value = property.GetValue(appConfig);
if (value is string stringValue)
{
// 替换路径中的占位符
if (stringValue.Contains("{Instance}") ||
stringValue.Contains("{instance}"))
{
var newValue = stringValue
.Replace("{Instance}", instanceId)
.Replace("{instance}", instanceId);
property.SetValue(appConfig, newValue);
Console.WriteLine($" 更新 {property.Name}: {newValue}");
}
else if (IsPathProperty(property.Name) &&
!stringValue.Contains(instanceId))
{
// 为路径属性添加实例ID
var newValue = $"{stringValue}_Instance{instanceId}";
property.SetValue(appConfig, newValue);
Console.WriteLine($" 更新 {property.Name}: {newValue}");
}
}
else if (property.PropertyType == typeof(int) &&
IsPortProperty(property.Name))
{
// 调整端口号
var basePort = (int)value;
var newPort = basePort + (int.Parse(instanceId) - 1) * 10;
property.SetValue(appConfig, newPort);
Console.WriteLine($" 更新 {property.Name}: {newPort}");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"设置实例配置时出错: {ex.Message}");
//serilogHelper?.Info($"设置实例配置时出错: {ex.Message}");
}
}
private static bool IsPortProperty(string propertyName)
{
return propertyName.ToLower().Contains("port");
}
private static bool IsPathProperty(string propertyName)
{
return propertyName.ToLower().Contains("path") ||
propertyName.ToLower().Contains("dir") ||
propertyName.ToLower().Contains("file");
}
public static IHostBuilder CreateHostBuilder(string[] args, string instanceId) =>
Host.CreateDefaultBuilder(args)
.UseSerilog((context, config) =>
{
// 为每个实例配置独立的Serilog
config.WriteTo.Console(
outputTemplate: $"[{{Timestamp:HH:mm:ss}} {{Level:u3}}] Instance{instanceId}: {{Message:lj}}{{NewLine}}{{Exception}}")
.WriteTo.File(
path: $"./Logs/{DateTime.UtcNow:yyyy-MM-dd}/log-.txt",
rollingInterval: RollingInterval.Day,
outputTemplate: $"[{{Timestamp:yyyy-MM-dd HH:mm:ss}} {{Level:u3}}] Instance{instanceId}: {{Message:lj}}{{NewLine}}{{Exception}}");
})
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureAppConfiguration((context, config) =>
{
// 清除默认配置,从头开始构建
config.Sources.Clear();
// 按优先级添加配置源
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.instance{instanceId}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables("INSTANCE_")
.AddCommandLine(args);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureKestrel(serverOptions =>
{
Console.WriteLine(int.Parse(instanceId));
serverOptions.ListenAnyIP(1 + (int.Parse(instanceId) - 1));
});
})
.ConfigureServices((context, services) =>
{
services.AddSingleton(new InstanceInfo { Id = instanceId });
});
public class InstanceInfo
{
public string Id { get; set; } = "1";
}
private static string GetInstanceId(string[] args)
{
// 支持多种参数格式
foreach (var arg in args)
{
if (arg.StartsWith("--instance"))
{
if (arg == "--instance")
{
// 查找下一个参数作为实例ID
var index = Array.IndexOf(args, arg);
if (index + 1 < args.Length)
{
return args[index + 1];
}
}
else if (arg.StartsWith("--instance="))
{
return arg.Substring("--instance=".Length);
}
else
{
// 格式: --instance1, --instance2
return arg.Substring("--instance".Length);
}
}
}
// 如果没有指定实例ID使用随机ID避免冲突
Random random = new Random();
return random.Next(0000, 9999).ToString();
}
/// <summary>
/// CreateHostBuilder
/// </summary>
@ -64,6 +235,7 @@ namespace SlnMesnac.WPF
/// <returns></returns>
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>

@ -5,10 +5,10 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SlnMesnac.WPF"
mc:Ignorable="d"
Title="MainWindow" WindowStartupLocation="CenterScreen" WindowState="Maximized" Height="1080" Width="1920" Topmost="False" Loaded="Window_Loaded" Closing="Window_Closing">
<Window.Background>
Title="汇集软件" WindowStartupLocation="CenterScreen" WindowState="Normal" Height="1000" Width="1420" Topmost="False" Loaded="Window_Loaded" Closing="Window_Closing">
<!--<Window.Background>
<ImageBrush ImageSource="/Templates/image/background.jpg" />
</Window.Background>
</Window.Background>-->
<Border Margin="5" Background="Transparent" CornerRadius="10">
<Border.Effect>
@ -17,10 +17,9 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="7*"/>
<RowDefinition Height="0.7*"/>
<!--<RowDefinition Height="0.7*"/>-->
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="Red" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="2,2">
<Grid>
@ -29,29 +28,17 @@
<ColumnDefinition Width="7*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center">
<!--<StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="数据采集控制系统" FontSize="50" Foreground="White" FontWeight="Bold"/>
</StackPanel>
</StackPanel>-->
<StackPanel Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Right">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- <TextBlock Grid.Column="0" Text="白班" FontSize="25" Foreground="White" FontWeight="Bold" Margin="0,0,30,0"/> -->
<!-- <TextBlock Grid.Column="1" Text="|" FontSize="25" Foreground="White" FontWeight="Bold" Margin="0,0,30,0"/> -->
<!-- <TextBlock Grid.Column="2" Text="SCADA" FontSize="25" Foreground="White" FontWeight="Bold" Margin="0,0,10,0"/> -->
</Grid>
</StackPanel>
</Grid>
</Border>
<Border Grid.Row="2" BorderBrush="Red" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="2,5,2,2">
<Border Grid.Row="0" BorderBrush="Red" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="2,5,2,2">
<ContentControl Content="{Binding UserContent}"/>
</Border>
<Border Grid.Row="3" BorderBrush="#1254AB" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="6,2,6,7">
<!--<Border Grid.Row="1" BorderBrush="#1254AB" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="6,2,6,7">
<Border.Effect>
<DropShadowEffect Color="#1254AB" Direction="270" BlurRadius="10" ShadowDepth="5" Opacity="0.5"/>
</Border.Effect>
@ -65,14 +52,14 @@
<Button Content="键 盘" Command="{Binding OpenSystemKeyboardCommand}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
<Button Content="最小化" x:Name="Minimized" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Minimized}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#FF9900" BorderBrush="#FF9900" Margin="0,0,10,0"/>
<Button Content="退 出" x:Name="Exit" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Exit}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#FF0033" BorderBrush="#FF0033" Margin="0,0,10,0"/>
<Button Content="型号切换" x:Name="ChangeType" Command="{Binding ControlOnClickCommand}" CommandParameter="{Binding Name,ElementName=ChangeType}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
<Button Content="功率设置" x:Name="ChangeType" Command="{Binding ControlOnClickCommand}" CommandParameter="{Binding Name,ElementName=ChangeType}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
<Button Content="代码生成" Visibility="Hidden" x:Name="Generate" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Generate}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">
<!--多行状态显示-->
--><!--多行状态显示--><!--
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
@ -153,15 +140,15 @@
</StackPanel>
</Grid>
<!--单行状态显示-->
--><!--单行状态显示--><!--
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<!--<ColumnDefinition Width="*"/>-->
--><!--<ColumnDefinition Width="*"/>--><!--
</Grid.ColumnDefinitions>
<!--<StackPanel Grid.Column="0">
--><!--<StackPanel Grid.Column="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
@ -252,14 +239,14 @@
<TextBlock Text="PLC状态" FontSize="15" Foreground="#FFFFFF" Margin="2,0,10,0"/>
</StackPanel>
</Grid>
</StackPanel>-->
</StackPanel>--><!--
</Grid>
</StackPanel>
</Grid>
</Border>
</Border>-->
</Grid>
</Border>

@ -0,0 +1,72 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.WPF.Model
{
public class RfidInfo : INotifyPropertyChanged
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public string Deviceid { get; set; } = null!;
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public string? Name { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public string? Connectstr { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public decimal? Connectmode { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public string? Devicetype { get; set; }
/// <summary>
/// 备 注:所属汇集软件ID
/// 默认值:
///</summary>
public string? Collectid { get; set; }
private string _isOnline ="未连接";
public string IsOnline
{
get { return _isOnline; }
set
{
if (_isOnline != value)
{
_isOnline = value;
OnPropertyChanged(nameof(IsOnline));
}
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

@ -0,0 +1,92 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SlnMesnac.WPF.Model
{
public class SenorInfo : INotifyPropertyChanged
{
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public string Sensorid { get; set; } = null!;
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public string Combineid { get; set; } = null!;
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public string? Name { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public decimal? Sensorser { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public decimal? Sensortypeid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public string? Deviceid { get; set; }
/// <summary>
/// 备 注:
/// 默认值:
///</summary>
public decimal? Readinterval { get; set; }
private string _readtime;
public string Readtime
{
get { return _readtime; }
set
{
if (_readtime != value)
{
_readtime = value;
OnPropertyChanged(nameof(Readtime));
}
}
}
private string _readdata;
public string Readdata
{
get { return _readdata; }
set
{
if (_readdata != value)
{
_readdata = value;
OnPropertyChanged(nameof(Readdata));
}
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

@ -0,0 +1,220 @@
<UserControl x:Class="SlnMesnac.WPF.Page.IndexPage.MiddleWare"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SlnMesnac.WPF.Page.IndexPage" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:converters="clr-namespace:SlnMesnac.WPF.Converter.Generate"
mc:Ignorable="d"
d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" Loaded="UserControl_Loaded">
<UserControl.Resources>
<Style x:Key="DataGridTextColumnCenterSytle" TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontSize" Value="18"/>
</Style>
<Style TargetType="DataGrid">
<!--网格线颜色-->
<Setter Property="CanUserResizeColumns" Value="false"/>
<Setter Property="Background" Value="#1152AC" />
<Setter Property="BorderBrush" Value="#4285DE" />
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalGridLinesBrush">
<Setter.Value>
<SolidColorBrush Color="#4285DE"/>
</Setter.Value>
</Setter>
<Setter Property="VerticalGridLinesBrush">
<Setter.Value>
<SolidColorBrush Color="#1152AC"/>
</Setter.Value>
</Setter>
</Style>
<!--列头标题栏样式-->
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="BorderBrush" Value="#dddddd" />
<Setter Property="Height" Value="40"/>
<Setter Property="FontSize" Value="18"/>
<Setter Property="Background" Value="#4285DE"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<!--单元格样式-->
<Style TargetType="DataGridCell">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="#4285DE" />
<Setter Property="Height" Value="40"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Grid Background="{TemplateBinding Background}" >
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#4285DE"/>
<Setter Property="Foreground" Value="#dddddd"/>
</Trigger>
</Style.Triggers>
</Style>
<converters:ConfigToDynamicGridViewConverter x:Key="ConfigToDynamicGridViewConverter"/>
<DataTemplate x:Key="LogMsgTemplate">
<TextBlock Text="{Binding}" FontSize="20" Foreground="Black" TextWrapping="Wrap" MaxWidth="800"/>
</DataTemplate>
<DataTemplate x:Key="FlightTemplate">
<StackPanel Margin="10,0,0,0">
<Button Content="{Binding StationName}" Foreground="Black"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid Margin="1 5 1 0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Grid.Column="0" BorderBrush="#0288d1" BorderThickness="1" CornerRadius="5" Background="Transparent" Margin="3,1,5,5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="9*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="#0288d1" BorderThickness="0,0,0,1" CornerRadius="0" Background="#1157b9" Margin="1,1,3,5" >
<TextBlock Text="日志信息" FontSize="20" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold"/>
</Border>
<!--扫描信息-->
<Border Grid.Row="1" BorderBrush="#0288d1" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="1,1,3,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border BorderThickness="0" Background="Transparent" CornerRadius="5" Margin="10,10,0,0" Grid.ColumnSpan="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="9*"/>
</Grid.RowDefinitions>
<!--<TextBlock Grid.Row="0" Text="日志信息" FontSize="18" Foreground="Black" HorizontalAlignment="Center" VerticalAlignment="Center"/>-->
<ScrollViewer Grid.Row="0" Foreground="Black" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<ItemsControl Foreground="Black" ItemsSource="{Binding LogMessages}" ItemTemplate="{StaticResource LogMsgTemplate}" />
</ScrollViewer>
</Grid>
</Border>
</Grid>
</Border>
</Grid>
</Border>
<Border Grid.Row="1" Grid.ColumnSpan="2" BorderBrush="#0288d1" BorderThickness="1" CornerRadius="5" Background="Transparent" Margin="3,1,3,5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="9*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="#0288d1" BorderThickness="0,0,0,1" CornerRadius="0" Background="Transparent" Margin="1,1,5,5" >
<TextBlock Text="传感器信息" FontSize="20" FontWeight="Bold" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<Border Grid.Row="1" BorderBrush="#0288d1" BorderThickness="1" CornerRadius="10" Background="Transparent" Margin="5,1,5,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="stackpanel1">
<DataGrid x:Name="senorlistDataGrid" Grid.Row="0" ItemsSource="{Binding Senorinfo}" Background="#00000000"
ColumnHeaderHeight="35" Height="{Binding Path=ActualHeight, ElementName=ScanPanel}"
RowHeight="50" AutoGenerateColumns="False" RowHeaderWidth="0" FontSize="20"
GridLinesVisibility="None" ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto" BorderThickness="0" CanUserAddRows="False" SelectionMode="Single" IsReadOnly="True" MaxHeight="400" VerticalScrollBarVisibility="Auto"
Foreground="Black" >
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<!-- 右键按下事件(最常用,右键点击立即触发) -->
<EventSetter Event="MouseRightButtonDown"
Handler="DataGridRow_MouseRightButtonDown"/>
<!-- 可选:右键释放事件(右键松开时触发) -->
<!-- <EventSetter Event="MouseRightButtonUp" Handler="DataGridRow_MouseRightButtonUp"/> -->
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Combineid}" Header="编号" Width="1*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}"/>
<DataGridTextColumn Binding="{Binding Name}" Header="名称" Width="1.5*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
<!--<DataGridTextColumn Binding="{Binding Sensorser}" Header="序号" Width="0.2*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
<DataGridTextColumn Binding="{Binding Sensortypeid}" Header="类型" Width="0.5*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />-->
<DataGridTextColumn Binding="{Binding Deviceid}" Header="设备编号" Width="1*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
<DataGridTextColumn Binding="{Binding Readinterval}" Header="时间间隔" Width="0.5*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
<DataGridTextColumn Binding="{Binding Readdata}" Header="数据" Width="1*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
<DataGridTextColumn Binding="{Binding Readtime}" Header="时间" Width="1*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>
</Border>
</Grid>
</Border>
<!--日志信息-->
<Border Grid.Row="0" Grid.Column="1" BorderBrush="#0288d1" BorderThickness="1" CornerRadius="5" Background="Transparent" Margin="3,1,3,5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="9*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="#0288d1" BorderThickness="0,0,0,1" CornerRadius="0" Background="Transparent" Margin="1,1,1,5" >
<Grid>
<TextBlock Text="设备信息" FontSize="20" FontWeight="Bold" Foreground="Black" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
</Border>
<Border Grid.Row="1" BorderBrush="#0288d1" BorderThickness="1" CornerRadius="10" Background="Transparent" Margin="5,1,5,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<StackPanel x:Name="stackpanel2">
<DataGrid Grid.Row="0" ItemsSource="{Binding Deviceinfo}" Background="#00000000"
ColumnHeaderHeight="35" Height="{Binding Path=ActualHeight, ElementName=ScanPanel}"
RowHeight="50" AutoGenerateColumns="False" RowHeaderWidth="0" FontSize="20"
GridLinesVisibility="None" ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto" BorderThickness="0" CanUserAddRows="False" IsReadOnly="True" SelectionMode="Extended" MaxHeight="400" VerticalScrollBarVisibility="Auto"
Foreground="Black" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Deviceid}" Header="编号" Width="1*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}"/>
<DataGridTextColumn Binding="{Binding Name}" Header="名称" Width="2.5*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
<DataGridTextColumn Binding="{Binding Connectstr}" Header="连接串" Width="2*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
<!--<DataGridTextColumn Binding="{Binding Connectmode}" Header="连接方式" Width="1*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />-->
<DataGridTextColumn Binding="{Binding Devicetype}" Header="设备类型" Width="1*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
<DataGridTextColumn Binding="{Binding Collectid}" Header="所属汇集" Width="0.7*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
<DataGridTextColumn Binding="{Binding IsOnline}" Header="连接状态" Width="1*" ElementStyle="{StaticResource DataGridTextColumnCenterSytle}" />
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>
</Border>
</Grid>
</Border>
</Grid>
</UserControl>

@ -0,0 +1,123 @@
using ATC_MaterialBind.Entity;
using Microsoft.Extensions.DependencyInjection;
using SlnMesnac.Model.domain;
using SlnMesnac.Model.dto;
using SlnMesnac.Plc;
using SlnMesnac.Rfid;
using SlnMesnac.WPF.Model;
using SlnMesnac.WPF.ViewModel.IndexPage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace SlnMesnac.WPF.Page.IndexPage
{
/// <summary>
/// MaterialBind.xaml 的交互逻辑
/// </summary>
public partial class MiddleWare : UserControl
{
public List<RfidAbsractFactory> rfidList;
MiddleWareViewModel indexContentViewModel;
public static Action<string, string> RefreshStateEvent;
public MiddleWare()
{
rfidList = App.ServiceProvider.GetRequiredService<List<RfidAbsractFactory>>();
InitializeComponent();
indexContentViewModel = new MiddleWareViewModel();
//indexContentViewModel._Action += RefreshStationQuallity;
this.DataContext = indexContentViewModel;
}
private void DataGridRow_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
// 1. 标记事件已处理,避免冒泡到父控件(可选,防止重复触发)
e.Handled = true;
// 2. 获取当前右键的行对象
if (sender is not DataGridRow row || row.DataContext is not SenorInfo selectedEmp) return;
// 2. 创建右键菜单(动态/静态均可)
var contextMenu = new ContextMenu();
var menuItem1 = new MenuItem { Header = $"修改" };
//var menuItem2 = new MenuItem { Header = $"读取" };
menuItem1.Click += (s, args) =>
{
SetPower setPowerContent = new SetPower(selectedEmp.Combineid);
setPowerContent.ShowDialog();
};
//menuItem2.Click += async (s, args) =>
//{
// List<TagInfo> rfid = await rfidList.Find(x=>x.ConfigKey == selectedEmp.Combineid).GetRFIDAsync();
// if (rfid != null && rfid.Count > 0)
// {
// rfid = rfid.Where((x, i) => rfid.FindIndex(z => z.EPCstring == x.EPCstring) == i).ToList();
// RefreshStateEvent?.Invoke(selectedEmp.Combineid, string.Join(",", rfid.Select(item => item.EPCstring)));
// }
//};
contextMenu.Items.Add(menuItem1);
//contextMenu.Items.Add(menuItem2);
// 3. 绑定菜单到当前行并显示
row.ContextMenu = contextMenu;
contextMenu.PlacementTarget = row;
contextMenu.IsOpen = true;
}
private void RefreshStationQuallity(List<StationQualityInfo> stationQualityInfos)
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
stackpanel1.Children.Clear();
if (stationQualityInfos != null && stationQualityInfos.Count > 0)
{
List<UIElement> buttons = new List<UIElement>();
foreach (var item in stationQualityInfos)
{
buttons.Add(new Button { FontSize = 20, Background = item.State == "1" ? Brushes.Lime : Brushes.Red, Height = 50, Content = item.StationName });
}
foreach (UIElement button in buttons)
{
stackpanel1.Children.Add(button);
}
}
else {
stackpanel1.Children.Remove(this);
}
}));
}
//在载入行的时候在行表头添加编号
private void dgv_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Header = (e.Row.GetIndex() + 1).ToString();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
}
}
}

@ -0,0 +1,18 @@
<Window x:Class="SlnMesnac.WPF.Page.IndexPage.SetPower"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SlnMesnac.WPF.Page.IndexPage"
mc:Ignorable="d"
Title="SetPower" Height="450" Width="800" WindowStartupLocation="CenterOwner" Loaded="Window_Loaded">
<Grid>
<Button x:Name="button" Content="获取" HorizontalAlignment="Left" Margin="461,79,0,0" VerticalAlignment="Top" Height="38" Width="107" Click="button_Click"/>
<Label x:Name="label" Content="当前功率" HorizontalAlignment="Left" Margin="170,85,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="textBox" FontSize="22" IsReadOnly="True" HorizontalAlignment="Left" Margin="270,83,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" RenderTransformOrigin="0.214,0.157"/>
<Button x:Name="button复制__C_" Content="写入" HorizontalAlignment="Left" Margin="461,148,0,0" VerticalAlignment="Top" Height="38" Width="107" Click="button复制__C__Click"/>
<Label x:Name="label复制__C_" Content="写入功率" HorizontalAlignment="Left" Margin="170,154,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="textBox复制__C_" FontSize="22" HorizontalAlignment="Left" Margin="270,152,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" RenderTransformOrigin="0.214,0.157"/>
</Grid>
</Window>

@ -0,0 +1,81 @@
using Microsoft.Extensions.DependencyInjection;
using SlnMesnac.Rfid;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace SlnMesnac.WPF.Page.IndexPage
{
/// <summary>
/// SetPower.xaml 的交互逻辑
/// </summary>
public partial class SetPower : Window
{
public List<RfidAbsractFactory> rfidList;
private string _combineID;
public SetPower(string combineID)
{
_combineID = combineID;
InitializeComponent();
}
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
try
{
rfidList = App.ServiceProvider.GetRequiredService<List<RfidAbsractFactory>>();
int DB = await rfidList.Find(x => x.ConfigKey == _combineID).Get_Rf();
textBox.Text = DB.ToString();
}
catch (Exception ex)
{
}
}
private async void button_Click(object sender, RoutedEventArgs e)
{
try
{
int DB = await rfidList.Find(x => x.ConfigKey == _combineID).Get_Rf();
textBox.Text = DB.ToString();
}
catch (Exception ex)
{
}
}
private async void button__C__Click(object sender, RoutedEventArgs e)
{
try
{
if (string.IsNullOrEmpty(textBox__C_.Text))
{
MessageBox.Show("写入功率不能为空!","注意",MessageBoxButton.OK,MessageBoxImage.Warning);
return;
}
bool iflag = await rfidList.Find(x => x.ConfigKey == _combineID).Set_Rf(int.Parse(textBox__C_.Text));
if (iflag)
{
MessageBox.Show("功率修改成功!");
}
}
catch (Exception ex)
{
}
}
}
}

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>

@ -43,7 +43,7 @@ namespace SlnMesnac.WPF
services.AddSqlSugarSetup();
//注册PLC工厂
services.AddPlcFactorySetup();
//services.AddPlcFactorySetup();
//注册httpClient
//services.AddHostedService<AirPorthttpClient>();
@ -52,7 +52,7 @@ namespace SlnMesnac.WPF
//services.AddHostedService<TcpServer>();
//注册RFID工厂
//services.AddRfidFactorySetup();
services.AddRfidFactorySetup();
//注册任务调度
//services.AddQuartzSetUp();
@ -83,6 +83,7 @@ namespace SlnMesnac.WPF
//启用Serilog中间件
app.UseSerilogExtensions();
app.UseTouchSocketExtensions();
//app.UseTouchSocketExtensions();
app.UseRouting();

@ -0,0 +1,291 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using GalaSoft.MvvmLight;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Models;
using SlnMesnac.Config;
using SlnMesnac.Repository;
using SlnMesnac.Rfid;
using SlnMesnac.TouchSocket;
using SlnMesnac.WPF.Model;
using SlnMesnac.WPF.Page.IndexPage;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using static Microsoft.WindowsAPICodePack.Shell.PropertySystem.SystemProperties.System;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
using Task = System.Threading.Tasks.Task;
namespace SlnMesnac.WPF.ViewModel.IndexPage
{
public partial class MiddleWareViewModel : ViewModelBase
{
private ILogger<MiddleWareViewModel> _logger;
private ISqlSugarClient? sqlSugarClient;
//容器里面的读写器集合
public List<RfidAbsractFactory> rfidList;
private AppConfig appConfig;
private ApiServer apiServer;
private MeshttpClient meshttpClient;
public MiddleWareViewModel()
{
appConfig = App.ServiceProvider.GetService<AppConfig>();
sqlSugarClient = App.ServiceProvider.GetService<ISqlSugarClient>();
rfidList = App.ServiceProvider.GetRequiredService<List<RfidAbsractFactory>>();
apiServer = App.ServiceProvider.GetService<ApiServer>();
meshttpClient = App.ServiceProvider.GetService<MeshttpClient>();
MiddleWare.RefreshStateEvent += RefreshEventArgs;
MeshttpClient.RefreshStateEvent += RefreshEventArgs;
MeshttpClient._RefreshLogMessageAction += RefreshLogMessage;
ApiServer.RefreshStateEvent += RefreshEventArgs;
ApiServer._RefreshLogMessageAction += RefreshLogMessage;
RefreshLogMessage("初始化");
LoadDeviceInfo();
LoadSenorInfo();
StartCheckStatus();
}
/// <summary>
/// 日志信息
/// </summary>
private ObservableCollection<string> _logMessages = new ObservableCollection<string>();
public ObservableCollection<string> LogMessages
{
get { return _logMessages; }
set
{
_logMessages = value;
RaisePropertyChanged(() => LogMessages);
}
}
/// <summary>
/// 刷新日志
/// </summary>
/// <param name="msg"></param>
public void RefreshLogMessage(string msg)
{
try
{
App.Current.Dispatcher.BeginInvoke((Action)(() =>
{
LogMessages.Add($"{DateTime.Now}: {msg}");
while (LogMessages.Count > 10)
{
LogMessages.RemoveAt(0);
}
var orderedList = LogMessages.OrderByDescending(x => x); // 排序后转为 List
LogMessages = new ObservableCollection<string>(orderedList);
}));
}
catch (Exception ex)
{
_logger.LogError($"异常:{ex.Message}");
}
}
public void RefreshEventArgs(string combineID, string rfid)
{
Senorinfo.FirstOrDefault(x => x.Combineid == combineID).Readtime = DateTime.Now.ToString("yy-MM-dd HH:mm:ss");
if (string.IsNullOrEmpty(rfid))
{
rfid = "Nodata";
}
Senorinfo.FirstOrDefault(x => x.Combineid == combineID).Readdata = rfid;
}
private ObservableCollection<RfidInfo> _Deviceinfo = new ObservableCollection<RfidInfo>();
public ObservableCollection<RfidInfo> Deviceinfo
{
get { return _Deviceinfo; }
set
{
_Deviceinfo = value;
RaisePropertyChanged(() => Deviceinfo);
}
}
private ObservableCollection<SenorInfo> _Senorinfo = new ObservableCollection<SenorInfo>();
public ObservableCollection<SenorInfo> Senorinfo
{
get { return _Senorinfo; }
set
{
_Senorinfo = value;
RaisePropertyChanged(() => Senorinfo);
}
}
private void LoadDeviceInfo()
{
List<Base_device_info> DeviceInfos = sqlSugarClient.Queryable<Base_device_info>().Where(expression: x =>x.Collectid == appConfig.StationCode).ToList();
App.Current.Dispatcher.Invoke(() =>
{
Deviceinfo.Clear();
foreach (var item in DeviceInfos)
{
RfidInfo rfid = new RfidInfo()
{
Name = item.Name,
Deviceid = item.Deviceid,
Collectid = item.Collectid,
Connectmode = item.Connectmode,
Connectstr = item.Connectstr,
Devicetype = item.Devicetype,
};
Deviceinfo.Add(rfid);
}
});
}
private void LoadSenorInfo()
{
List<Base_sensor_info> SenorInfos = sqlSugarClient.Queryable<Base_sensor_info>().ToList();
Senorinfo.Clear();
foreach (var item in Deviceinfo)
{
Base_sensor_info base_Sensor_Info = SenorInfos.Find(x => x.Deviceid == item.Deviceid);
App.Current.Dispatcher.Invoke(() =>
{
SenorInfo senorInfo = new SenorInfo()
{
Combineid = base_Sensor_Info.Combineid,
Name = base_Sensor_Info.Name,
Sensorid = base_Sensor_Info.Sensorid,
Sensortypeid = base_Sensor_Info.Sensortypeid,
Deviceid =base_Sensor_Info.Deviceid,
Readinterval = base_Sensor_Info.Readinterval,
};
Senorinfo.Add(senorInfo);
});
}
}
private List<List<RfidAbsractFactory>> SplitListIntoBatches(List<RfidAbsractFactory> sourceList, int batchSize)
{
var batches = new List<List<RfidAbsractFactory>>();
for (int i = 0; i < sourceList.Count; i += batchSize)
{
// 截取每批的设备最后一批可能不足10个
var batch = sourceList.Skip(i).Take(batchSize).ToList();
batches.Add(batch);
}
return batches;
}
private async Task DetectDeviceBatchAsync(List<RfidAbsractFactory> batch)
{
// 并行检测当前批次的设备(可选,根据接口性能调整)
var detectionTasks = batch.Select(device => DetectSingleDeviceAsync(device));
// 等待当前批次所有设备检测完成
await Task.WhenAll(detectionTasks);
}
private async Task DetectSingleDeviceAsync(RfidAbsractFactory device)
{
try
{
//device.Close();
bool status = device.GetOnlineStatus();
if (!status)
{
status = await device.ConnectAsync(device.ip, device.port,device.ConfigKey);
if (!status)
{
Deviceinfo.FirstOrDefault(x => x.Connectstr == $"{device.ip}:{device.port}").IsOnline = "未连接";
}
else
{
Deviceinfo.FirstOrDefault(x => x.Connectstr == $"{device.ip}:{device.port}").IsOnline = "已连接";
}
}
else
{
//更新界面状态
Deviceinfo.FirstOrDefault(x => x.Connectstr == $"{device.ip}:{device.port}").IsOnline = "已连接";
}
}
catch (Exception ex)
{
}
}
private void StartCheckStatus()
{
Task.Run(async () =>
{
while (true)
{
try
{
#region RFID状态
//RefreshLogMessage("检测设备状态");
var batches = SplitListIntoBatches(rfidList, 10);
for (int i = 0; i < batches.Count; i++)
{
var currentBatch = batches[i];
// 显示当前批次信息UI线程
//Console.WriteLine($"开始检测第{i + 1}批(共{currentBatch.Count}个设备)\r\n");
// 异步检测当前批次的设备状态不阻塞UI
await DetectDeviceBatchAsync(currentBatch);
// 批次之间的间隔(最后一批无需等待)
if (i < batches.Count - 1)
{
//Console.WriteLine( $"第{i + 1}批检测完成,共{batches.Count}批,等待{1000 / 1000}秒后检测下一批\r\n");
await Task.Delay(10);
}
}
//foreach (var rfid in rfidList)
//{
// if (rfid.ConfigKey == "C031040701")
// {
// }
// bool status = rfid.GetOnlineStatus();
// if (!status)
// {
// status = await rfid.ConnectAsync(rfid.ip, rfid.port);
// if (!status)
// {
// Deviceinfo.FirstOrDefault(x => x.Connectstr == $"{rfid.ip}:{rfid.port}").IsOnline = "未连接";
// }
// else
// {
// Deviceinfo.FirstOrDefault(x => x.Connectstr == $"{rfid.ip}:{rfid.port}").IsOnline = "已连接";
// }
// }
// else
// {
// //更新界面状态
// Deviceinfo.FirstOrDefault(x => x.Connectstr == $"{rfid.ip}:{rfid.port}").IsOnline = "已连接";
// }
//}
#endregion RFID状态
}
catch (Exception ex)
{
//_logger.Error($"监听设备状态异常:{ex.Message}");
}
await Task.Delay(1000 * 30);
}
});
}
}
}

@ -24,11 +24,12 @@ namespace SlnMesnac.WPF.ViewModel
private IAGVStateService _AGVStateService;
private TcpServer _tcpServer;
//代码生成
private readonly GenerateControl generateControl = new GenerateControl();
private MaterialBind indexContent = new MaterialBind();
//private readonly GenerateControl generateControl = new GenerateControl();
private MiddleWare indexContent = new MiddleWare();
//private ChangeType changeType = new ChangeType();
private AppConfig _appConfig;
private AirPorthttpClient _airPorthttpClient;
private MeshttpClient _airPorthttpClient;
#region 参数定义
/// <summary>
@ -113,7 +114,7 @@ namespace SlnMesnac.WPF.ViewModel
_AGVStateService = App.ServiceProvider.GetService<IAGVStateService>();
_BaseTaskInfoBusinesslogger = App.ServiceProvider.GetService<ILogger<BaseTaskInfoBusiness>>();
_tcpServer = App.ServiceProvider.GetService<TcpServer>();
_airPorthttpClient = App.ServiceProvider.GetService<AirPorthttpClient>();
_airPorthttpClient = App.ServiceProvider.GetService<MeshttpClient>();
BaseTaskInfoBusiness.GetInstance(_BaseTaskInfoBusinesslogger, _Taskservice, _AGVStateService, _tcpServer, _airPorthttpClient);
ControlOnClickCommand = new RelayCommand<object>(obj => ControlOnClick(obj));
FormControlCommand = new RelayCommand<object>(x => FormControl(x));
@ -144,7 +145,7 @@ namespace SlnMesnac.WPF.ViewModel
Application.Current.Shutdown();
break;
case "Generate":
UserContent = generateControl;
//UserContent = generateControl;
break;
//case "ChangeType":
// UserContent = changeType;

@ -14,7 +14,7 @@
"configId": "mes",
"dbType": 1,
//"connStr": "server=192.168.1.120;uid=sa;pwd=123456;database=ATJ_581_DB"
"connStr": "server=119.45.202.115;uid=sa;pwd=haiwei@123;database=ATJ_581_DB"
"connStr": "server=119.45.202.115;uid=sa;pwd=haiwei@123;database=WLDB"
},
{
"configId": "Local",
@ -71,7 +71,7 @@
"ComPort": "COM1",
"StationCode": "150"
"StationCode": "101"
},
"ProductConfig": {
@ -79,7 +79,7 @@
"NGCount": "0"
},
"ChangeTypeConfig": {
"ProductType": "E34F",
"ProductType": "E34FU",
"KTProductType": "E34F",
"OpenFlag": "1"
}

Loading…
Cancel
Save