using BPASmart.Model; using BPA.Helper; using BPA.Communication; using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Communication; 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("通讯模块初始化"); RedisHelper.GetInstance.ConnectAsync(); 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 => { //switch (temp.Key) //{ // case EDataType.Bool: // temp.Value?.ForEach(value => // { // //var res = modbusTcpMaster.ReadBool(value.StartAddress.ToString(), value.Length); // var res = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length); // SetValue(res.Content, item.DeviceName, value, 1); // }); // break; // case EDataType.Byte: // break; // case EDataType.Int: // break; // case EDataType.Word: // temp.Value?.ForEach(value => // { // //var res = modbusTcpMaster.ReadUshort(value.StartAddress.ToString(), value.Length); // var res = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length); // SetValue(res.Content, item.DeviceName, value, 1); // }); // break; // case EDataType.Dint: // break; // case EDataType.Dword: // temp.Value?.ForEach(value => // { // //var res = modbusTcpMaster.ReadUint(value.StartAddress.ToString(), value.Length); // var res = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length); // SetValue(res.Content, item.DeviceName, value, 2); // }); // break; // case EDataType.Float: // temp.Value?.ForEach(value => // { // //var res = modbusTcpMaster.ReadFloat(value.StartAddress.ToString(), value.Length); // var res = modbusTcpMaster.Read(value.StartAddress.ToString(), value.Length); // SetValue(res.Content, item.DeviceName, value, 2); // }); // break; // default: // break; //} 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.ModbusTcpConnect(_modbusTcp.IP, _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("DistributedHostComputer/Control"); ThreadManage.GetInstance().StartLong(new Action(() => { while (msg.Count > 0) { DeviceControl(); } Thread.Sleep(100); }), "MQTT 消息监听"); }); mqttHelper.MessageRecive = new Action((s) => { msg.Enqueue(s); }); } private void DeviceControl() { if (msg.TryDequeue(out string s)) { var res = JsonConvert.DeserializeObject(s); if (res != null) { res.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)); CommunicationDevices[item.DeviceName].Write(address, Convert.ToBoolean(item.Value)); break; case EDataType.Byte: //CommunicationDevices[item.DeviceName].Write(address, Convert.ToByte(item.Value)); CommunicationDevices[item.DeviceName].Write(address, Convert.ToByte(item.Value)); break; case EDataType.Int: //CommunicationDevices[item.DeviceName].Write(address, Convert.ToInt16(item.Value)); CommunicationDevices[item.DeviceName].Write(address, Convert.ToInt16(item.Value)); break; case EDataType.Word: //CommunicationDevices[item.DeviceName].Write(address, Convert.ToUInt16(item.Value)); CommunicationDevices[item.DeviceName].Write(address, Convert.ToUInt16(item.Value)); break; case EDataType.Dint: //CommunicationDevices[item.DeviceName].Write(address, Convert.ToInt32(item.Value)); CommunicationDevices[item.DeviceName].Write(address, Convert.ToInt32(item.Value)); break; case EDataType.Dword: //CommunicationDevices[item.DeviceName].Write(address, Convert.ToUInt32(item.Value)); CommunicationDevices[item.DeviceName].Write(address, Convert.ToUInt32(item.Value)); break; case EDataType.Float: //CommunicationDevices[item.DeviceName].Write(address, Convert.ToSingle(item.Value)); CommunicationDevices[item.DeviceName].Write(address, Convert.ToSingle(item.Value)); break; default: break; } } } }); } } } //private void SetValue(TArray[] arrays, string DeviceName, ReadDataModel readDataModel, ushort by) //{ // if (arrays != null) // { // 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[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.SetValue($"{Devicename}", reeisDataModels); // } // } //} //private ushort GetBySize(EDataType eDataType) //{ // switch (eDataType) // { // case EDataType.Bool: // case EDataType.Byte: // case EDataType.Int: // case EDataType.Word: // return 1; // case EDataType.Dint: // case EDataType.Dword: // case EDataType.Float: // return 2; // case EDataType.Double: // break; // case EDataType.String: // break; // default: // break; // } // return 1; //} 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.SetValue($"{Devicename}", reeisDataModels); } } } //private Dictionary> GetReadDataModels(CommunicationModel communicationModel) //{ // Dictionary> readDataModels = new Dictionary>(); // communicationModel.VarTableModels.GroupBy(p => p.DataType)?.ToList()?.ForEach(tempVar => // { // if (tempVar.Key != null && tempVar.Key.Length > 0) // { // //int address = tempVar.Min(p => p.RealAddress); // EDataType dataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.Key); // switch (dataType) // { // case EDataType.Bool: // case EDataType.Byte: // case EDataType.Int: // case EDataType.Word: // if (!readDataModels.ContainsKey(dataType)) readDataModels.TryAdd(dataType, GetDataGroup(tempVar)); // break; // case EDataType.Dint: // case EDataType.Dword: // case EDataType.Float: // if (!readDataModels.ContainsKey(dataType)) readDataModels.TryAdd(dataType, GetDataGroup(tempVar, 2)); // break; // default: // break; // } // } // }); // return readDataModels; //} //private List GetDataGroup(IGrouping variableInfos, int by = 1) //{ // List ReturnValue = new List(); // var res = variableInfos?.OrderBy(p => p.RealAddress).ToList(); // List RealAddresss = new List(); // variableInfos.ToList()?.ForEach(item => { if (int.TryParse(item.RealAddress, out int add)) RealAddresss.Add(add); }); // int count = 0; // if (res != null) // { // //int address = variableInfos.Min(p => p.RealAddress); // int address = RealAddresss.Min(); // int startAddress = address; // for (int i = 0; i < res.Count; i++) // { // if (int.TryParse(res.ElementAt(i).RealAddress, out int TempAddress)) // { // if (TempAddress == address) // { // count++; // address += by; // } // else // { // ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); // count = 1; // address = TempAddress + by; // startAddress = TempAddress; // } // } // } // ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); // } // return ReturnValue; //} } }