using BPASmart.Model; using BPA.Helper; using BPA.Communication; using Microsoft.EntityFrameworkCore.Metadata.Conventions; using System.Collections.Concurrent; using Newtonsoft.Json; namespace BPASmart.Server { internal class CommunicationServer : IServer { ConcurrentDictionary CommunicationDevices = new ConcurrentDictionary(); public void Init() { BPASmartClient.Message.MessageLog.GetInstance.ShowDebugLog("通讯模块初始化"); MessageLog.GetInstance.NotifyShow = new Action((s) => { BPASmartClient.Message.MessageLog.GetInstance.ShowDebugLog(s); }); RedisHelper.GetInstance.Connect(new ConfigurationOptions() { ServerAddress = $"124.222.238.75:16000", Password = "123456", }); MqttInit(); Json.Data.CommunicationDevices.ToList()?.ForEach(item => { ThreadManage.GetInstance().Start(new Action(() => { switch (item.CommDevice) { case BPASmart.Model.ModbusRtu _modbusRtu: break; case BPASmart.Model.ModbusTcp _modbusTcp: BPA.Communication.ModbusTcp modbusTcpMaster = new BPA.Communication.ModbusTcp(); modbusTcpMaster.ConnectOk = new Action(() => { if (!CommunicationDevices.ContainsKey(item.DeviceName)) CommunicationDevices.TryAdd(item.DeviceName, modbusTcpMaster); ThreadManage.GetInstance().StartLong(new Action(() => { item.VarTableModels.GetReadDataModels().ToList()?.ForEach(temp => { Array ResultArray = null; temp.Value?.ForEach(value => { switch (temp.Key) { case EDataType.Bool: ResultArray = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length)?.Content; break; case EDataType.Byte: break; case EDataType.Int: ResultArray = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length)?.Content; break; case EDataType.Word: ResultArray = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length)?.Content; break; case EDataType.Dint: ResultArray = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length)?.Content; break; case EDataType.Dword: ResultArray = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length)?.Content; break; case EDataType.Float: ResultArray = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length)?.Content; break; default: break; } SetValue(ResultArray, item.DeviceName, value, temp.Key); }); }); Thread.Sleep(100); }), $"{item.DeviceName} 设备数据采集"); var DeviceModel = item; }); modbusTcpMaster.IsReconnect = true; modbusTcpMaster.Connect(new ConfigurationOptions() { IpAddress = _modbusTcp.IP, Port = _modbusTcp.PortNum }); break; case BPASmart.Model.Siemens _siemens: break; default: break; } }), $"{item.DeviceName} 初始化连接"); }); } ConcurrentQueue msg = new ConcurrentQueue(); private void MqttInit() { MqttHelper mqttHelper = new MqttHelper(); mqttHelper.Connect("admin", "fengyoufu067101!@#", "124.222.238.75", 61613, $"分布式上位机:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); mqttHelper.ConnectOk = new Action(() => { mqttHelper.Subscrib(Topics.DeviceControl); ThreadManage.GetInstance().StartLong(new Action(() => { while (msg.Count > 0) { if (msg.TryDequeue(out string s)) { var res = JsonConvert.DeserializeObject(s) as IMessage; if (res != null) { if (res is PublishInfo _mPublishInfo) { DeviceControl(_mPublishInfo); } } } } Thread.Sleep(100); }), "MQTT 消息监听"); }); mqttHelper.MessageRecive = new Action((s) => { msg.Enqueue(s); }); } private void DeviceControl(PublishInfo publishInfo) { publishInfo.PublishModels.ForEach(item => { if (CommunicationDevices.ContainsKey(item.DeviceName)) { string address = string.Empty; if (item.RealAddress != null && item.RealAddress.Length > 0) address = item.DeviceName; else { var res = Json.Data.CommunicationDevices.FirstOrDefault(p => p.DeviceName == item.DeviceName); var res2 = res?.VarTableModels.FirstOrDefault(p => p.VarName?.Length > 0 && p.VarName == item.VarName); address = res2?.RealAddress; } if (item.Value != null && item.Value.Length > 0) { switch (item.DataType) { case EDataType.Bool: CommunicationDevices[item.DeviceName].Write(address, Convert.ToBoolean(item.Value)); break; case EDataType.Byte: CommunicationDevices[item.DeviceName].Write(address, Convert.ToByte(item.Value)); break; case EDataType.Int: CommunicationDevices[item.DeviceName].Write(address, Convert.ToInt16(item.Value)); break; case EDataType.Word: CommunicationDevices[item.DeviceName].Write(address, Convert.ToUInt16(item.Value)); break; case EDataType.Dint: CommunicationDevices[item.DeviceName].Write(address, Convert.ToInt32(item.Value)); break; case EDataType.Dword: CommunicationDevices[item.DeviceName].Write(address, Convert.ToUInt32(item.Value)); break; case EDataType.Float: CommunicationDevices[item.DeviceName].Write(address, Convert.ToSingle(item.Value)); break; default: break; } } } }); } private void SetValue(Array arrays, string DeviceName, ReadDataModel readDataModel, EDataType eDataType) { if (arrays != null) { ushort by = eDataType.GetEDataSize(); int index = Array.FindIndex(Json.Data.CommunicationDevices.ToArray(), p => p.DeviceName == DeviceName);//获取设备所在集合位置 if (index >= 0 && index < Json.Data.CommunicationDevices.Count) { var tempArray = Json.Data.CommunicationDevices.ElementAt(index).VarTableModels.ToArray(); for (int i = 0; i < arrays.Length; i++) { int varIndex = Array.FindIndex(tempArray, p => p.RealAddress == (readDataModel.StartAddress + (i * by)).ToString()); if (varIndex >= 0 && varIndex < tempArray.Length) { Json.Data.CommunicationDevices.ElementAt(index).VarTableModels.ElementAt(varIndex).CurrentValue = arrays.GetValue(i)?.ToString(); } } var Devicename = Json.Data.CommunicationDevices[index].DeviceName; List reeisDataModels = new List(); Json.Data.CommunicationDevices[index].VarTableModels.ToList().ForEach(tempVar => { if (tempVar.VarName.Length > 0) { reeisDataModels.Add(new ReeisDataModel() { VarName = tempVar.VarName, VarVaule = tempVar.CurrentValue, DataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.DataType) }); } }); RedisHelper.GetInstance.Write($"{Devicename}", reeisDataModels); } } } } }