@@ -12,10 +12,10 @@ namespace BPASmart.Model | |||||
public static AddressConvert GetInstance => _Instance ?? (_Instance = new AddressConvert()); | public static AddressConvert GetInstance => _Instance ?? (_Instance = new AddressConvert()); | ||||
private AddressConvert() { } | private AddressConvert() { } | ||||
public int PlcConverter(ICommunicationDevice device, string Address) | |||||
public string PlcConverter(ICommunicationDevice device, string Address) | |||||
{ | { | ||||
int address = -1; | |||||
if (Address != null && int.TryParse(Address, out int result)) return result; | |||||
string address = string.Empty; | |||||
//if (Address != null && int.TryParse(Address, out int result)) return result; | |||||
if (device != null && Address != null && Address.Length > 0) | if (device != null && Address != null && Address.Length > 0) | ||||
{ | { | ||||
switch (device) | switch (device) | ||||
@@ -24,7 +24,7 @@ namespace BPASmart.Model | |||||
if (Address.ToUpper().Contains("LW") && Address.Length >= 3) | if (Address.ToUpper().Contains("LW") && Address.Length >= 3) | ||||
{ | { | ||||
var res = Address.Substring(2); | var res = Address.Substring(2); | ||||
if (res != null && int.TryParse(res, out int LwAddress)) return LwAddress; | |||||
if (res != null && int.TryParse(res, out int LwAddress)) return LwAddress.ToString(); | |||||
} | } | ||||
break; | break; | ||||
case kinco _tempKinco: | case kinco _tempKinco: | ||||
@@ -37,7 +37,7 @@ namespace BPASmart.Model | |||||
{ | { | ||||
if (ExitAddress >= 0 && ExitAddress <= 7) | if (ExitAddress >= 0 && ExitAddress <= 7) | ||||
{ | { | ||||
return (firstAddress * 8) + 320 + ExitAddress; | |||||
return ((firstAddress * 8) + 320 + ExitAddress).ToString(); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -45,14 +45,14 @@ namespace BPASmart.Model | |||||
else if ((Address.ToUpper().Contains("VW") || Address.ToUpper().Contains("VD")) && Address.Length >= 3) | else if ((Address.ToUpper().Contains("VW") || Address.ToUpper().Contains("VD")) && Address.Length >= 3) | ||||
{ | { | ||||
var res = Address.Substring(2); | var res = Address.Substring(2); | ||||
if (res != null && int.TryParse(res, out int tempAddress)) return (tempAddress / 2) + 100; | |||||
if (res != null && int.TryParse(res, out int tempAddress)) return ((tempAddress / 2) + 100).ToString(); | |||||
} | } | ||||
break; | break; | ||||
case KincoOneMachine _tempKincoOneMachine: | case KincoOneMachine _tempKincoOneMachine: | ||||
if (Address.ToUpper().Contains("D") && Address.Length >= 2) | if (Address.ToUpper().Contains("D") && Address.Length >= 2) | ||||
{ | { | ||||
var res = Address.Substring(1); | var res = Address.Substring(1); | ||||
if (res != null && int.TryParse(res, out int LwAddress)) return LwAddress; | |||||
if (res != null && int.TryParse(res, out int LwAddress)) return LwAddress.ToString(); | |||||
} | } | ||||
break; | break; | ||||
default: | default: | ||||
@@ -9,8 +9,9 @@ namespace BPASmart.Model | |||||
public class PublishModel | public class PublishModel | ||||
{ | { | ||||
public string DeviceName { get; set; } | public string DeviceName { get; set; } | ||||
public string Address { get; set; } | |||||
public string RealAddress { get; set; } | |||||
public string Value { get; set; } | public string Value { get; set; } | ||||
public EDataType DataType { get; set; } | |||||
public int Sleep { get; set; } | public int Sleep { get; set; } | ||||
} | } | ||||
@@ -56,8 +56,8 @@ namespace BPASmart.Model | |||||
{ | { | ||||
_mAddress = value; | _mAddress = value; | ||||
OnPropertyChanged(); | OnPropertyChanged(); | ||||
int address = AddressConvert.GetInstance.PlcConverter(DeviceType, value); | |||||
if (address >= 0) RealAddress = address; | |||||
string address = AddressConvert.GetInstance.PlcConverter(DeviceType, value); | |||||
if (address.Length > 0) RealAddress = address; | |||||
} | } | ||||
} | } | ||||
private string _mAddress = string.Empty; | private string _mAddress = string.Empty; | ||||
@@ -65,7 +65,7 @@ namespace BPASmart.Model | |||||
/// <summary> | /// <summary> | ||||
/// 实际地址 | /// 实际地址 | ||||
/// </summary> | /// </summary> | ||||
public int RealAddress { get; set; } | |||||
public string RealAddress { get; set; } | |||||
/// <summary> | /// <summary> | ||||
/// 数据类型 | /// 数据类型 | ||||
@@ -7,7 +7,7 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="BPA.Communication" Version="1.0.9" /> | |||||
<PackageReference Include="BPA.Communication" Version="1.0.10" /> | |||||
<PackageReference Include="BPA.Helper" Version="1.0.6" /> | <PackageReference Include="BPA.Helper" Version="1.0.6" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -3,17 +3,24 @@ using BPA.Helper; | |||||
using BPA.Communication; | using BPA.Communication; | ||||
using Microsoft.EntityFrameworkCore.Metadata.Conventions; | using Microsoft.EntityFrameworkCore.Metadata.Conventions; | ||||
using Communication; | using Communication; | ||||
using System.Collections.Concurrent; | |||||
using Newtonsoft.Json; | |||||
namespace BPASmart.Server | namespace BPASmart.Server | ||||
{ | { | ||||
internal class CommunicationServer : IServer | internal class CommunicationServer : IServer | ||||
{ | { | ||||
ConcurrentDictionary<string, ICommunication> CommunicationDevices = new ConcurrentDictionary<string, ICommunication>(); | |||||
public void Init() | public void Init() | ||||
{ | { | ||||
var tt = sizeof(bool); | |||||
BPASmartClient.Message.MessageLog.GetInstance.ShowDebugLog("通讯模块初始化"); | BPASmartClient.Message.MessageLog.GetInstance.ShowDebugLog("通讯模块初始化"); | ||||
RedisHelper.GetInstance.ConnectAsync(); | RedisHelper.GetInstance.ConnectAsync(); | ||||
MqttInit(); | |||||
Json<CommunicationPar>.Data.CommunicationDevices.ToList()?.ForEach(item => | Json<CommunicationPar>.Data.CommunicationDevices.ToList()?.ForEach(item => | ||||
{ | { | ||||
ThreadManage.GetInstance().Start(new Action(() => | ThreadManage.GetInstance().Start(new Action(() => | ||||
{ | { | ||||
switch (item.CommDevice) | switch (item.CommDevice) | ||||
@@ -24,6 +31,8 @@ namespace BPASmart.Server | |||||
BPA.Communication.ModbusTcp modbusTcpMaster = new BPA.Communication.ModbusTcp(); | BPA.Communication.ModbusTcp modbusTcpMaster = new BPA.Communication.ModbusTcp(); | ||||
modbusTcpMaster.ConnectOk = new Action(() => | modbusTcpMaster.ConnectOk = new Action(() => | ||||
{ | { | ||||
if (!CommunicationDevices.ContainsKey(item.DeviceName)) | |||||
CommunicationDevices.TryAdd(item.DeviceName, modbusTcpMaster); | |||||
ThreadManage.GetInstance().StartLong(new Action(() => | ThreadManage.GetInstance().StartLong(new Action(() => | ||||
{ | { | ||||
GetReadDataModels(item).ToList()?.ForEach(temp => | GetReadDataModels(item).ToList()?.ForEach(temp => | ||||
@@ -33,8 +42,8 @@ namespace BPASmart.Server | |||||
case EDataType.Bool: | case EDataType.Bool: | ||||
temp.Value?.ForEach(value => | temp.Value?.ForEach(value => | ||||
{ | { | ||||
var res = modbusTcpMaster.ReadCoils(value.StartAddress, value.Length); | |||||
SetValue(res, item.DeviceName, value, 1); | |||||
var res = modbusTcpMaster.ReadBool(value.StartAddress.ToString(), value.Length); | |||||
SetValue(res.Content, item.DeviceName, value, 1); | |||||
}); | }); | ||||
break; | break; | ||||
case EDataType.Byte: | case EDataType.Byte: | ||||
@@ -44,8 +53,8 @@ namespace BPASmart.Server | |||||
case EDataType.Word: | case EDataType.Word: | ||||
temp.Value?.ForEach(value => | temp.Value?.ForEach(value => | ||||
{ | { | ||||
var res = modbusTcpMaster.ReadHoldingRegisters(value.StartAddress, value.Length); | |||||
SetValue(res, item.DeviceName, value, 1); | |||||
var res = modbusTcpMaster.ReadUshort(value.StartAddress.ToString(), value.Length); | |||||
SetValue(res.Content, item.DeviceName, value, 1); | |||||
}); | }); | ||||
break; | break; | ||||
case EDataType.Dint: | case EDataType.Dint: | ||||
@@ -53,15 +62,15 @@ namespace BPASmart.Server | |||||
case EDataType.Dword: | case EDataType.Dword: | ||||
temp.Value?.ForEach(value => | temp.Value?.ForEach(value => | ||||
{ | { | ||||
var res = modbusTcpMaster.ReadHoldingRegisters(value.StartAddress, value.Length); | |||||
SetValue(res, item.DeviceName, value, 2); | |||||
var res = modbusTcpMaster.ReadUint(value.StartAddress.ToString(), value.Length); | |||||
SetValue(res.Content, item.DeviceName, value, 2); | |||||
}); | }); | ||||
break; | break; | ||||
case EDataType.Float: | case EDataType.Float: | ||||
temp.Value?.ForEach(value => | temp.Value?.ForEach(value => | ||||
{ | { | ||||
var res = modbusTcpMaster.ReadHoldingRegisters(value.StartAddress, value.Length); | |||||
SetValue(res, item.DeviceName, value, 2); | |||||
var res = modbusTcpMaster.ReadFloat(value.StartAddress.ToString(), value.Length); | |||||
SetValue(res.Content, item.DeviceName, value, 2); | |||||
}); | }); | ||||
break; | break; | ||||
default: | default: | ||||
@@ -85,6 +94,72 @@ namespace BPASmart.Server | |||||
}); | }); | ||||
} | } | ||||
ConcurrentQueue<string> msg = new ConcurrentQueue<string>(); | |||||
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<string>((s) => | |||||
{ | |||||
msg.Enqueue(s); | |||||
}); | |||||
} | |||||
private void DeviceControl() | |||||
{ | |||||
if (msg.TryDequeue(out string s)) | |||||
{ | |||||
var res = JsonConvert.DeserializeObject<PublishInfo>(s); | |||||
if (res != null) | |||||
{ | |||||
res.PublishModels.ForEach(item => | |||||
{ | |||||
if (CommunicationDevices.ContainsKey(item.DeviceName)) | |||||
{ | |||||
switch (item.DataType) | |||||
{ | |||||
case EDataType.Bool: | |||||
CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToBoolean(item.Value)); | |||||
break; | |||||
case EDataType.Byte: | |||||
CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToByte(item.Value)); | |||||
break; | |||||
case EDataType.Int: | |||||
CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToInt16(item.Value)); | |||||
break; | |||||
case EDataType.Word: | |||||
CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToUInt16(item.Value)); | |||||
break; | |||||
case EDataType.Dint: | |||||
CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToInt32(item.Value)); | |||||
break; | |||||
case EDataType.Dword: | |||||
CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToUInt32(item.Value)); | |||||
break; | |||||
case EDataType.Float: | |||||
CommunicationDevices[item.DeviceName].Write(item.RealAddress, Convert.ToSingle(item.Value)); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
}); | |||||
} | |||||
} | |||||
} | |||||
private void SetValue<TArray>(TArray[] arrays, string DeviceName, ReadDataModel readDataModel, ushort by) | private void SetValue<TArray>(TArray[] arrays, string DeviceName, ReadDataModel readDataModel, ushort by) | ||||
{ | { | ||||
if (arrays != null) | if (arrays != null) | ||||
@@ -95,7 +170,7 @@ namespace BPASmart.Server | |||||
var tempArray = Json<CommunicationPar>.Data.CommunicationDevices.ElementAt(index).VarTableModels.ToArray(); | var tempArray = Json<CommunicationPar>.Data.CommunicationDevices.ElementAt(index).VarTableModels.ToArray(); | ||||
for (int i = 0; i < arrays.Length; i++) | for (int i = 0; i < arrays.Length; i++) | ||||
{ | { | ||||
int varIndex = Array.FindIndex(tempArray, p => p.RealAddress == readDataModel.StartAddress + (i * by)); | |||||
int varIndex = Array.FindIndex(tempArray, p => p.RealAddress == (readDataModel.StartAddress + (i * by)).ToString()); | |||||
if (varIndex >= 0 && varIndex < tempArray.Length) | if (varIndex >= 0 && varIndex < tempArray.Length) | ||||
{ | { | ||||
Json<CommunicationPar>.Data.CommunicationDevices.ElementAt(index).VarTableModels.ElementAt(varIndex).CurrentValue = arrays[i].ToString(); | Json<CommunicationPar>.Data.CommunicationDevices.ElementAt(index).VarTableModels.ElementAt(varIndex).CurrentValue = arrays[i].ToString(); | ||||
@@ -126,7 +201,7 @@ namespace BPASmart.Server | |||||
{ | { | ||||
if (tempVar.Key != null && tempVar.Key.Length > 0) | if (tempVar.Key != null && tempVar.Key.Length > 0) | ||||
{ | { | ||||
int address = tempVar.Min(p => p.RealAddress); | |||||
//int address = tempVar.Min(p => p.RealAddress); | |||||
EDataType dataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.Key); | EDataType dataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.Key); | ||||
switch (dataType) | switch (dataType) | ||||
{ | { | ||||
@@ -153,25 +228,32 @@ namespace BPASmart.Server | |||||
{ | { | ||||
List<ReadDataModel> ReturnValue = new List<ReadDataModel>(); | List<ReadDataModel> ReturnValue = new List<ReadDataModel>(); | ||||
var res = variableInfos?.OrderBy(p => p.RealAddress).ToList(); | var res = variableInfos?.OrderBy(p => p.RealAddress).ToList(); | ||||
List<int> RealAddresss = new List<int>(); | |||||
variableInfos.ToList()?.ForEach(item => { if (int.TryParse(item.RealAddress, out int add)) RealAddresss.Add(add); }); | |||||
int count = 0; | int count = 0; | ||||
if (res != null) | if (res != null) | ||||
{ | { | ||||
int address = variableInfos.Min(p => p.RealAddress); | |||||
//int address = variableInfos.Min(p => p.RealAddress); | |||||
int address = RealAddresss.Min(); | |||||
int startAddress = address; | int startAddress = address; | ||||
for (int i = 0; i < res.Count; i++) | for (int i = 0; i < res.Count; i++) | ||||
{ | { | ||||
if (res.ElementAt(i).RealAddress == address) | |||||
if (int.TryParse(res.ElementAt(i).RealAddress, out int TempAddress)) | |||||
{ | { | ||||
count++; | |||||
address += by; | |||||
} | |||||
else | |||||
{ | |||||
ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); | |||||
count = 1; | |||||
address = res.ElementAt(i).RealAddress + by; | |||||
startAddress = res.ElementAt(i).RealAddress; | |||||
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 }); | ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); | ||||
} | } | ||||
@@ -29,7 +29,7 @@ | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="BPA.Communication" Version="1.0.9" /> | |||||
<PackageReference Include="BPA.Communication" Version="1.0.10" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -287,7 +287,7 @@ namespace BPASmart.VariableManager.ViewModels | |||||
{ | { | ||||
for (int i = 0; i < arrays.Length; i++) | for (int i = 0; i < arrays.Length; i++) | ||||
{ | { | ||||
int varIndex = Array.FindIndex(varialeInfos.ToArray(), p => p.RealAddress == readDataModel.StartAddress + (i * by)); | |||||
int varIndex = Array.FindIndex(varialeInfos.ToArray(), p => p.RealAddress == (readDataModel.StartAddress + (i * by)).ToString()); | |||||
if (varIndex >= 0 && varIndex < varialeInfos.Count) | if (varIndex >= 0 && varIndex < varialeInfos.Count) | ||||
{ | { | ||||
varialeInfos.ElementAt(varIndex).CurrentValue = arrays[i].ToString(); | varialeInfos.ElementAt(varIndex).CurrentValue = arrays[i].ToString(); | ||||
@@ -302,7 +302,7 @@ namespace BPASmart.VariableManager.ViewModels | |||||
{ | { | ||||
if (tempVar.Key != null && tempVar.Key.Length > 0) | if (tempVar.Key != null && tempVar.Key.Length > 0) | ||||
{ | { | ||||
int address = tempVar.Min(p => p.RealAddress); | |||||
//int address = tempVar.Min(p => p.RealAddress); | |||||
EDataType dataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.Key); | EDataType dataType = (EDataType)Enum.Parse(typeof(EDataType), tempVar.Key); | ||||
switch (dataType) | switch (dataType) | ||||
{ | { | ||||
@@ -327,27 +327,59 @@ namespace BPASmart.VariableManager.ViewModels | |||||
private List<ReadDataModel> GetDataGroup(IGrouping<string, VariableInfo> variableInfos, int by = 1) | private List<ReadDataModel> GetDataGroup(IGrouping<string, VariableInfo> variableInfos, int by = 1) | ||||
{ | { | ||||
//List<ReadDataModel> ReturnValue = new List<ReadDataModel>(); | |||||
//var res = variableInfos?.OrderBy(p => p.RealAddress).ToList(); | |||||
//int count = 0; | |||||
//if (res != null) | |||||
//{ | |||||
// int address = variableInfos.Min(p => p.RealAddress); | |||||
// int startAddress = address; | |||||
// for (int i = 0; i < res.Count; i++) | |||||
// { | |||||
// if (res.ElementAt(i).RealAddress == address) | |||||
// { | |||||
// count++; | |||||
// address += by; | |||||
// } | |||||
// else | |||||
// { | |||||
// ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); | |||||
// count = 1; | |||||
// address = res.ElementAt(i).RealAddress + by; | |||||
// startAddress = res.ElementAt(i).RealAddress; | |||||
// } | |||||
// } | |||||
// ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); | |||||
//} | |||||
//return ReturnValue; | |||||
List<ReadDataModel> ReturnValue = new List<ReadDataModel>(); | List<ReadDataModel> ReturnValue = new List<ReadDataModel>(); | ||||
var res = variableInfos?.OrderBy(p => p.RealAddress).ToList(); | var res = variableInfos?.OrderBy(p => p.RealAddress).ToList(); | ||||
List<int> RealAddresss = new List<int>(); | |||||
variableInfos.ToList()?.ForEach(item => { if (int.TryParse(item.RealAddress, out int add)) RealAddresss.Add(add); }); | |||||
int count = 0; | int count = 0; | ||||
if (res != null) | if (res != null) | ||||
{ | { | ||||
int address = variableInfos.Min(p => p.RealAddress); | |||||
int address = RealAddresss.Min(); | |||||
int startAddress = address; | int startAddress = address; | ||||
for (int i = 0; i < res.Count; i++) | for (int i = 0; i < res.Count; i++) | ||||
{ | { | ||||
if (res.ElementAt(i).RealAddress == address) | |||||
{ | |||||
count++; | |||||
address += by; | |||||
} | |||||
else | |||||
if (int.TryParse(res.ElementAt(i).RealAddress, out int TempAddress)) | |||||
{ | { | ||||
ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); | |||||
count = 1; | |||||
address = res.ElementAt(i).RealAddress + by; | |||||
startAddress = res.ElementAt(i).RealAddress; | |||||
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 }); | ReturnValue.Add(new ReadDataModel() { StartAddress = (ushort)startAddress, Length = (ushort)count }); | ||||
} | } | ||||
@@ -7,7 +7,9 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> | |||||
<PackageReference Include="S7netplus" Version="0.14.0" /> | <PackageReference Include="S7netplus" Version="0.14.0" /> | ||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="6.0.0" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
</Project> | </Project> |
@@ -0,0 +1,205 @@ | |||||
using Newtonsoft.Json.Linq; | |||||
using S7.Net.Types; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Globalization; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.S7Net | |||||
{ | |||||
public static class Conversion | |||||
{ | |||||
/// <summary> | |||||
/// 将二进制字符串转换为 Int32 值 | |||||
/// </summary> | |||||
/// <param name="txt"></param> | |||||
/// <returns></returns> | |||||
public static int BinStringToInt32(this string txt) | |||||
{ | |||||
int num = 0; | |||||
for (int i = 0; i < txt.Length; i++) | |||||
{ | |||||
num = (num << 1) | ((txt[i] == '1') ? 1 : 0); | |||||
} | |||||
return num; | |||||
} | |||||
/// <summary> | |||||
/// 将二进制字符串转换为字节。 可以返回空值。 | |||||
/// </summary> | |||||
/// <param name="txt"></param> | |||||
/// <returns></returns> | |||||
public static byte? BinStringToByte(this string txt) | |||||
{ | |||||
if (txt.Length == 8) | |||||
{ | |||||
return (byte)txt.BinStringToInt32(); | |||||
} | |||||
return null; | |||||
} | |||||
/// <summary> | |||||
/// 将值转换为二进制字符串 | |||||
/// </summary> | |||||
/// <param name="value"></param> | |||||
/// <returns></returns> | |||||
public static string ValToBinString(this object value) | |||||
{ | |||||
int num = 0; | |||||
int num2 = 0; | |||||
int num3 = 0; | |||||
string text = ""; | |||||
long num4 = 0L; | |||||
try | |||||
{ | |||||
if (value.GetType().Name.IndexOf("[]") < 0) | |||||
{ | |||||
switch (value.GetType().Name) | |||||
{ | |||||
case "Byte": | |||||
num3 = 7; | |||||
num4 = (byte)value; | |||||
break; | |||||
case "Int16": | |||||
num3 = 15; | |||||
num4 = (short)value; | |||||
break; | |||||
case "Int32": | |||||
num3 = 31; | |||||
num4 = (int)value; | |||||
break; | |||||
case "Int64": | |||||
num3 = 63; | |||||
num4 = (long)value; | |||||
break; | |||||
default: | |||||
throw new Exception(); | |||||
} | |||||
for (num = num3; num >= 0; num += -1) | |||||
{ | |||||
text = (((num4 & (long)Math.Pow(2.0, num)) <= 0) ? (text + "0") : (text + "1")); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
switch (value.GetType().Name) | |||||
{ | |||||
case "Byte[]": | |||||
{ | |||||
num3 = 7; | |||||
byte[] array4 = (byte[])value; | |||||
for (num2 = 0; num2 <= array4.Length - 1; num2++) | |||||
{ | |||||
for (num = num3; num >= 0; num += -1) | |||||
{ | |||||
text = (((array4[num2] & (byte)Math.Pow(2.0, num)) <= 0) ? (text + "0") : (text + "1")); | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
case "Int16[]": | |||||
{ | |||||
num3 = 15; | |||||
short[] array2 = (short[])value; | |||||
for (num2 = 0; num2 <= array2.Length - 1; num2++) | |||||
{ | |||||
for (num = num3; num >= 0; num += -1) | |||||
{ | |||||
text = (((array2[num2] & (byte)Math.Pow(2.0, num)) <= 0) ? (text + "0") : (text + "1")); | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
case "Int32[]": | |||||
{ | |||||
num3 = 31; | |||||
int[] array3 = (int[])value; | |||||
for (num2 = 0; num2 <= array3.Length - 1; num2++) | |||||
{ | |||||
for (num = num3; num >= 0; num += -1) | |||||
{ | |||||
text = (((array3[num2] & (byte)Math.Pow(2.0, num)) <= 0) ? (text + "0") : (text + "1")); | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
case "Int64[]": | |||||
{ | |||||
num3 = 63; | |||||
byte[] array = (byte[])value; | |||||
for (num2 = 0; num2 <= array.Length - 1; num2++) | |||||
{ | |||||
for (num = num3; num >= 0; num += -1) | |||||
{ | |||||
text = (((array[num2] & (byte)Math.Pow(2.0, num)) <= 0) ? (text + "0") : (text + "1")); | |||||
} | |||||
} | |||||
break; | |||||
} | |||||
default: | |||||
throw new Exception(); | |||||
} | |||||
} | |||||
return text; | |||||
} | |||||
catch | |||||
{ | |||||
return ""; | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 获取字节指定位的值 | |||||
/// </summary> | |||||
/// <param name="data"></param> | |||||
/// <param name="bitPosition"></param> | |||||
/// <returns></returns> | |||||
public static bool SelectBit(this byte data, int bitPosition) | |||||
{ | |||||
int num = 1 << bitPosition; | |||||
return (data & num) != 0; | |||||
} | |||||
public static short ConvertToShort(this ushort input) | |||||
{ | |||||
return short.Parse(input.ToString("X"), NumberStyles.HexNumber); | |||||
} | |||||
public static ushort ConvertToUshort(this short input) | |||||
{ | |||||
return ushort.Parse(input.ToString("X"), NumberStyles.HexNumber); | |||||
} | |||||
public static int ConvertToInt(this uint input) | |||||
{ | |||||
return int.Parse(input.ToString("X"), NumberStyles.HexNumber); | |||||
} | |||||
public static uint ConvertToUInt(this int input) | |||||
{ | |||||
return uint.Parse(input.ToString("X"), NumberStyles.HexNumber); | |||||
} | |||||
public static uint ConvertToUInt(this float input) | |||||
{ | |||||
return DWord.FromByteArray(Real.ToByteArray(input)); | |||||
} | |||||
public static float ConvertToFloat(this uint input) | |||||
{ | |||||
return Real.FromByteArray(DWord.ToByteArray(input)); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,357 @@ | |||||
using Newtonsoft.Json.Linq; | |||||
using S7.Net.Types; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.ComponentModel.Design; | |||||
using System.Linq; | |||||
using System.Reflection; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.S7Net | |||||
{ | |||||
public static class EntityClassResolution | |||||
{ | |||||
private static IEnumerable<PropertyInfo> GetAccessableProperties(Type classType) | |||||
{ | |||||
return from p in classType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty) | |||||
where p.GetSetMethod() != null | |||||
select p; | |||||
} | |||||
private static double GetIncreasedNumberOfBytes(double numBytes, Type type) | |||||
{ | |||||
switch (type.Name) | |||||
{ | |||||
case "Boolean": | |||||
numBytes += 0.125; | |||||
break; | |||||
case "Byte": | |||||
numBytes += 1.0; | |||||
break; | |||||
case "Int16": | |||||
case "UInt16": | |||||
case "Ushort": | |||||
case "Short": | |||||
numBytes += 2.0; | |||||
break; | |||||
case "Int32": | |||||
case "UInt32": | |||||
case "Single": | |||||
case "float": | |||||
numBytes += 4.0; | |||||
break; | |||||
case "Double": | |||||
numBytes += 8.0; | |||||
break; | |||||
case "String": | |||||
numBytes += 256.0; | |||||
break; | |||||
default: | |||||
numBytes = GetClassSize(Activator.CreateInstance(type), numBytes, isInnerProperty: true); | |||||
break; | |||||
} | |||||
return numBytes; | |||||
} | |||||
/// <summary> | |||||
/// 获取实体类的字节大小 | |||||
/// </summary> | |||||
/// <param name="instance"></param> | |||||
/// <param name="numBytes"></param> | |||||
/// <param name="isInnerProperty"></param> | |||||
/// <returns></returns> | |||||
/// <exception cref="Exception"></exception> | |||||
public static double GetClassSize(object instance, double numBytes = 0.0, bool isInnerProperty = false) | |||||
{ | |||||
foreach (PropertyInfo accessableProperty in GetAccessableProperties(instance.GetType())) | |||||
{ | |||||
if (accessableProperty.PropertyType.IsArray) | |||||
{ | |||||
Type elementType = accessableProperty.PropertyType.GetElementType(); | |||||
Array array = (Array)accessableProperty.GetValue(instance, null); | |||||
if (array.Length <= 0) | |||||
{ | |||||
throw new Exception("Cannot determine size of class, because an array is defined which has no fixed size greater than zero."); | |||||
} | |||||
IncrementToEven(ref numBytes); | |||||
for (int i = 0; i < array.Length; i++) | |||||
{ | |||||
numBytes = GetIncreasedNumberOfBytes(numBytes, elementType); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
numBytes = GetIncreasedNumberOfBytes(numBytes, accessableProperty.PropertyType); | |||||
} | |||||
} | |||||
if (!isInnerProperty) | |||||
{ | |||||
numBytes = Math.Ceiling(numBytes); | |||||
if (numBytes / 2.0 - Math.Floor(numBytes / 2.0) > 0.0) | |||||
{ | |||||
numBytes += 1.0; | |||||
} | |||||
} | |||||
return numBytes; | |||||
} | |||||
private static object? GetPropertyValue(Type propertyType, byte[] bytes, ref double numBytes) | |||||
{ | |||||
object obj = null; | |||||
switch (propertyType.Name) | |||||
{ | |||||
case "Boolean": | |||||
{ | |||||
int num = (int)Math.Floor(numBytes); | |||||
int num2 = (int)((numBytes - (double)num) / 0.125); | |||||
obj = (((bytes[num] & (int)Math.Pow(2.0, num2)) == 0) ? ((object)false) : ((object)true)); | |||||
numBytes += 0.125; | |||||
break; | |||||
} | |||||
case "Byte": | |||||
numBytes = Math.Ceiling(numBytes); | |||||
obj = bytes[(int)numBytes]; | |||||
numBytes += 1.0; | |||||
break; | |||||
case "Int16": | |||||
numBytes = Math.Ceiling(numBytes); | |||||
if (numBytes / 2.0 - Math.Floor(numBytes / 2.0) > 0.0) | |||||
{ | |||||
numBytes += 1.0; | |||||
} | |||||
obj = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]).ConvertToShort(); | |||||
numBytes += 2.0; | |||||
break; | |||||
case "UInt16": | |||||
numBytes = Math.Ceiling(numBytes); | |||||
if (numBytes / 2.0 - Math.Floor(numBytes / 2.0) > 0.0) | |||||
{ | |||||
numBytes += 1.0; | |||||
} | |||||
obj = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]); | |||||
numBytes += 2.0; | |||||
break; | |||||
case "Int32": | |||||
numBytes = Math.Ceiling(numBytes); | |||||
if (numBytes / 2.0 - Math.Floor(numBytes / 2.0) > 0.0) | |||||
{ | |||||
numBytes += 1.0; | |||||
} | |||||
obj = DWord.FromBytes(bytes[(int)numBytes + 3], bytes[(int)numBytes + 2], bytes[(int)numBytes + 1], bytes[(int)numBytes]).ConvertToInt(); | |||||
numBytes += 4.0; | |||||
break; | |||||
case "UInt32": | |||||
numBytes = Math.Ceiling(numBytes); | |||||
if (numBytes / 2.0 - Math.Floor(numBytes / 2.0) > 0.0) | |||||
{ | |||||
numBytes += 1.0; | |||||
} | |||||
obj = DWord.FromBytes(bytes[(int)numBytes], bytes[(int)numBytes + 1], bytes[(int)numBytes + 2], bytes[(int)numBytes + 3]); | |||||
numBytes += 4.0; | |||||
break; | |||||
case "Single": | |||||
numBytes = Math.Ceiling(numBytes); | |||||
if (numBytes / 2.0 - Math.Floor(numBytes / 2.0) > 0.0) | |||||
{ | |||||
numBytes += 1.0; | |||||
} | |||||
obj = Real.FromByteArray(new byte[4] | |||||
{ | |||||
bytes[(int)numBytes], | |||||
bytes[(int)numBytes + 1], | |||||
bytes[(int)numBytes + 2], | |||||
bytes[(int)numBytes + 3] | |||||
}); | |||||
numBytes += 4.0; | |||||
break; | |||||
case "Double": | |||||
{ | |||||
numBytes = Math.Ceiling(numBytes); | |||||
if (numBytes / 2.0 - Math.Floor(numBytes / 2.0) > 0.0) | |||||
{ | |||||
numBytes += 1.0; | |||||
} | |||||
byte[] array = new byte[8]; | |||||
Array.Copy(bytes, (int)numBytes, array, 0, 8); | |||||
obj = LReal.FromByteArray(array); | |||||
numBytes += 8.0; | |||||
break; | |||||
} | |||||
case "String": | |||||
byte[] sarray = new byte[256]; | |||||
Array.Copy(bytes, (int)numBytes, sarray, 0, 256); | |||||
obj = GetGb2312()?.GetString(sarray).Trim().Replace(" ", "").Replace("\n", ""); | |||||
numBytes += 256.0; | |||||
break; | |||||
default: | |||||
{ | |||||
object obj2 = Activator.CreateInstance(propertyType); | |||||
numBytes = FromBytes(obj2, bytes, numBytes); | |||||
obj = obj2; | |||||
break; | |||||
} | |||||
} | |||||
return obj; | |||||
} | |||||
private static Encoding GetGb2312() | |||||
{ | |||||
//获取指定的编码不存在的时候需要安装 System.Text.Encoding.CodePages nuget包 | |||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); | |||||
return Encoding.GetEncoding("gb2312"); | |||||
} | |||||
public static double FromBytes(object sourceClass, byte[] bytes, double numBytes = 0.0, bool isInnerClass = false) | |||||
{ | |||||
if (bytes == null) | |||||
{ | |||||
return numBytes; | |||||
} | |||||
foreach (PropertyInfo accessableProperty in GetAccessableProperties(sourceClass.GetType())) | |||||
{ | |||||
if (accessableProperty.PropertyType.IsArray) | |||||
{ | |||||
Array array = (Array)accessableProperty.GetValue(sourceClass, null); | |||||
IncrementToEven(ref numBytes); | |||||
Type elementType = accessableProperty.PropertyType.GetElementType(); | |||||
for (int i = 0; i < array.Length; i++) | |||||
{ | |||||
if (!(numBytes < (double)bytes.Length)) | |||||
{ | |||||
break; | |||||
} | |||||
array.SetValue(GetPropertyValue(elementType, bytes, ref numBytes), i); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
accessableProperty.SetValue(sourceClass, GetPropertyValue(accessableProperty.PropertyType, bytes, ref numBytes), null); | |||||
} | |||||
} | |||||
return numBytes; | |||||
} | |||||
private static double SetBytesFromProperty(object propertyValue, byte[] bytes, double numBytes) | |||||
{ | |||||
int num = 0; | |||||
int num2 = 0; | |||||
byte[] array = null; | |||||
switch (propertyValue.GetType().Name) | |||||
{ | |||||
case "Boolean": | |||||
num = (int)Math.Floor(numBytes); | |||||
num2 = (int)((numBytes - (double)num) / 0.125); | |||||
if ((bool)propertyValue) | |||||
{ | |||||
bytes[num] |= (byte)Math.Pow(2.0, num2); | |||||
} | |||||
else | |||||
{ | |||||
bytes[num] &= (byte)(~(byte)Math.Pow(2.0, num2)); | |||||
} | |||||
numBytes += 0.125; | |||||
break; | |||||
case "Byte": | |||||
numBytes = (int)Math.Ceiling(numBytes); | |||||
num = (int)numBytes; | |||||
bytes[num] = (byte)propertyValue; | |||||
numBytes += 1.0; | |||||
break; | |||||
case "Int16": | |||||
array = Int.ToByteArray((short)propertyValue); | |||||
break; | |||||
case "UInt16": | |||||
array = Word.ToByteArray((ushort)propertyValue); | |||||
break; | |||||
case "Int32": | |||||
array = DInt.ToByteArray((int)propertyValue); | |||||
break; | |||||
case "UInt32": | |||||
array = DWord.ToByteArray((uint)propertyValue); | |||||
break; | |||||
case "Single": | |||||
array = Real.ToByteArray((float)propertyValue); | |||||
break; | |||||
case "Double": | |||||
array = LReal.ToByteArray((double)propertyValue); | |||||
break; | |||||
case "String": | |||||
array = new byte[256]; | |||||
var res = GetGb2312()?.GetBytes(propertyValue?.ToString()); | |||||
for (int i = 0; i < res?.Length; i++) { array[i] = res[i]; } | |||||
break; | |||||
default: | |||||
numBytes = ToBytes(propertyValue, bytes, numBytes); | |||||
break; | |||||
} | |||||
if (array != null) | |||||
{ | |||||
IncrementToEven(ref numBytes); | |||||
num = (int)numBytes; | |||||
for (int i = 0; i < array.Length; i++) | |||||
{ | |||||
bytes[num + i] = array[i]; | |||||
} | |||||
numBytes += (double)array.Length; | |||||
} | |||||
return numBytes; | |||||
} | |||||
public static double ToBytes(object sourceClass, byte[] bytes, double numBytes = 0.0) | |||||
{ | |||||
foreach (PropertyInfo accessableProperty in GetAccessableProperties(sourceClass.GetType())) | |||||
{ | |||||
if (accessableProperty.PropertyType.IsArray) | |||||
{ | |||||
Array array = (Array)accessableProperty.GetValue(sourceClass, null); | |||||
IncrementToEven(ref numBytes); | |||||
accessableProperty.PropertyType.GetElementType(); | |||||
for (int i = 0; i < array.Length; i++) | |||||
{ | |||||
if (!(numBytes < (double)bytes.Length)) | |||||
{ | |||||
break; | |||||
} | |||||
numBytes = SetBytesFromProperty(array.GetValue(i), bytes, numBytes); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
numBytes = SetBytesFromProperty(accessableProperty.GetValue(sourceClass, null), bytes, numBytes); | |||||
} | |||||
} | |||||
return numBytes; | |||||
} | |||||
private static void IncrementToEven(ref double numBytes) | |||||
{ | |||||
numBytes = Math.Ceiling(numBytes); | |||||
if (numBytes % 2.0 > 0.0) | |||||
{ | |||||
numBytes += 1.0; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -29,10 +29,10 @@ namespace BPASmartClient.S7Net | |||||
myPlc?.Close(); | myPlc?.Close(); | ||||
} | } | ||||
public object Read(string address) | |||||
public TResult Read<TResult>(string address) | |||||
{ | { | ||||
if (!IsConnected) return default; | if (!IsConnected) return default; | ||||
return myPlc?.Read(address); | |||||
return (TResult)myPlc?.Read(address); | |||||
} | } | ||||
public bool[] ReadBools(int address, int count) | public bool[] ReadBools(int address, int count) | ||||
@@ -43,55 +43,76 @@ namespace BPASmartClient.S7Net | |||||
return default; | return default; | ||||
} | } | ||||
public ushort[] ReadMW(int address, int count) | |||||
{ | |||||
if (!IsConnected) return default; | |||||
var res = Read(DataType.Memory, 0, address, VarType.Word, count); | |||||
if (res != null && res is ushort[] ReturnValue) return ReturnValue; | |||||
return default; | |||||
} | |||||
public float[] ReadMD(int address, int count) | |||||
{ | |||||
if (!IsConnected) return default; | |||||
var res = Read(DataType.Memory, 0, address, VarType.Real, count); | |||||
if (res != null && res is float[] ReturnValue) return ReturnValue; | |||||
return default; | |||||
} | |||||
private object Read(DataType dataType, int db, int address, VarType varType, int count) | private object Read(DataType dataType, int db, int address, VarType varType, int count) | ||||
{ | { | ||||
if (!IsConnected) return default; | if (!IsConnected) return default; | ||||
return myPlc?.Read(dataType, db, address, varType, count); | return myPlc?.Read(dataType, db, address, varType, count); | ||||
} | } | ||||
public void Write(string address, object value) | |||||
public void Write<TValue>(string address, TValue value) | |||||
{ | { | ||||
myPlc?.Write(address, value); | myPlc?.Write(address, value); | ||||
} | } | ||||
public ReadT ReadStruct<ReadT>(int db, int startAddress = 0) | |||||
public TResult ReadClass<TResult>(int db, int startByteAdr = 0) where TResult : class, new() | |||||
{ | { | ||||
if (!IsConnected) return default; | |||||
return (ReadT)myPlc.ReadStruct(typeof(ReadT), db, startAddress); | |||||
TResult sourceClass = new TResult(); | |||||
int num = (int)EntityClassResolution.GetClassSize(sourceClass); | |||||
if (num <= 0) return sourceClass; | |||||
byte[] array = myPlc.ReadBytes(DataType.DataBlock, db, startByteAdr, num); | |||||
EntityClassResolution.FromBytes(sourceClass, array); | |||||
return sourceClass; | |||||
} | } | ||||
public void WriteStruct(object structValue, int db, int startAddress = 0) | |||||
public void WriteClass<TWriteModel>(TWriteModel sourceClass, int db, int startAddress = 0) where TWriteModel : class, new() | |||||
{ | { | ||||
myPlc?.WriteStruct(structValue, db, startAddress); | |||||
byte[] array = new byte[(int)EntityClassResolution.GetClassSize(sourceClass)]; | |||||
EntityClassResolution.ToBytes(sourceClass, array); | |||||
myPlc.WriteBytes(DataType.DataBlock, db, startAddress, array); | |||||
} | } | ||||
public int ReadClass(object sourceClass, int db, int startAddress = 0) | |||||
{ | |||||
if (!IsConnected) return -1; | |||||
return myPlc.ReadClass(sourceClass, db, startAddress); | |||||
} | |||||
//public ushort[] ReadMW(int address, int count) | |||||
//{ | |||||
// if (!IsConnected) return default; | |||||
// var res = Read(DataType.Memory, 0, address, VarType.Word, count); | |||||
// if (res != null && res is ushort[] ReturnValue) return ReturnValue; | |||||
// return default; | |||||
//} | |||||
public void WriteClass(object sourceClass, int db, int startAddress = 0) | |||||
{ | |||||
myPlc?.WriteClass(sourceClass, db, startAddress); | |||||
} | |||||
//public float[] ReadMD(int address, int count) | |||||
//{ | |||||
// if (!IsConnected) return default; | |||||
// var res = Read(DataType.Memory, 0, address, VarType.Real, count); | |||||
// if (res != null && res is float[] ReturnValue) return ReturnValue; | |||||
// return default; | |||||
//} | |||||
//public ReadT ReadStruct<ReadT>(int db, int startAddress = 0) | |||||
//{ | |||||
// if (!IsConnected) return default; | |||||
// return (ReadT)myPlc.ReadStruct(typeof(ReadT), db, startAddress); | |||||
//} | |||||
//public void WriteStruct(object structValue, int db, int startAddress = 0) | |||||
//{ | |||||
// myPlc?.WriteStruct(structValue, db, startAddress); | |||||
//} | |||||
//public int ReadClass(object sourceClass, int db, int startAddress = 0) | |||||
//{ | |||||
// if (!IsConnected) return -1; | |||||
// return myPlc.ReadClass(sourceClass, db, startAddress); | |||||
//} | |||||
//public void WriteClass(object sourceClass, int db, int startAddress = 0) | |||||
//{ | |||||
// myPlc?.WriteClass(sourceClass, db, startAddress); | |||||
//} | |||||
} | } | ||||
} | } |
@@ -0,0 +1,20 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<OutputType>WinExe</OutputType> | |||||
<TargetFramework>net6.0-windows</TargetFramework> | |||||
<Nullable>enable</Nullable> | |||||
<UseWindowsForms>true</UseWindowsForms> | |||||
<ImplicitUsings>enable</ImplicitUsings> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="BPA.Communication" Version="1.0.10" /> | |||||
<PackageReference Include="BPA.Helper" Version="1.0.6" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\BPASmart.Model\BPASmart.Model.csproj" /> | |||||
</ItemGroup> | |||||
</Project> |
@@ -0,0 +1,135 @@ | |||||
namespace ComputerTestDemo | |||||
{ | |||||
partial class Form1 | |||||
{ | |||||
/// <summary> | |||||
/// Required designer variable. | |||||
/// </summary> | |||||
private System.ComponentModel.IContainer components = null; | |||||
/// <summary> | |||||
/// Clean up any resources being used. | |||||
/// </summary> | |||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||||
protected override void Dispose(bool disposing) | |||||
{ | |||||
if (disposing && (components != null)) | |||||
{ | |||||
components.Dispose(); | |||||
} | |||||
base.Dispose(disposing); | |||||
} | |||||
#region Windows Form Designer generated code | |||||
/// <summary> | |||||
/// Required method for Designer support - do not modify | |||||
/// the contents of this method with the code editor. | |||||
/// </summary> | |||||
private void InitializeComponent() | |||||
{ | |||||
this.button1 = new System.Windows.Forms.Button(); | |||||
this.label1 = new System.Windows.Forms.Label(); | |||||
this.comboBox1 = new System.Windows.Forms.ComboBox(); | |||||
this.comboBox2 = new System.Windows.Forms.ComboBox(); | |||||
this.label2 = new System.Windows.Forms.Label(); | |||||
this.label3 = new System.Windows.Forms.Label(); | |||||
this.textBox1 = new System.Windows.Forms.TextBox(); | |||||
this.SuspendLayout(); | |||||
// | |||||
// button1 | |||||
// | |||||
this.button1.Location = new System.Drawing.Point(203, 173); | |||||
this.button1.Name = "button1"; | |||||
this.button1.Size = new System.Drawing.Size(121, 37); | |||||
this.button1.TabIndex = 0; | |||||
this.button1.Text = "设定值"; | |||||
this.button1.UseVisualStyleBackColor = true; | |||||
this.button1.Click += new System.EventHandler(this.button1_Click); | |||||
// | |||||
// label1 | |||||
// | |||||
this.label1.AutoSize = true; | |||||
this.label1.Font = new System.Drawing.Font("华文楷体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); | |||||
this.label1.Location = new System.Drawing.Point(100, 40); | |||||
this.label1.Name = "label1"; | |||||
this.label1.Size = new System.Drawing.Size(115, 23); | |||||
this.label1.TabIndex = 1; | |||||
this.label1.Text = "选择设备:"; | |||||
// | |||||
// comboBox1 | |||||
// | |||||
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; | |||||
this.comboBox1.FormattingEnabled = true; | |||||
this.comboBox1.Location = new System.Drawing.Point(203, 40); | |||||
this.comboBox1.Name = "comboBox1"; | |||||
this.comboBox1.Size = new System.Drawing.Size(121, 25); | |||||
this.comboBox1.TabIndex = 2; | |||||
this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); | |||||
// | |||||
// comboBox2 | |||||
// | |||||
this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; | |||||
this.comboBox2.FormattingEnabled = true; | |||||
this.comboBox2.Location = new System.Drawing.Point(203, 80); | |||||
this.comboBox2.Name = "comboBox2"; | |||||
this.comboBox2.Size = new System.Drawing.Size(121, 25); | |||||
this.comboBox2.TabIndex = 3; | |||||
// | |||||
// label2 | |||||
// | |||||
this.label2.AutoSize = true; | |||||
this.label2.Font = new System.Drawing.Font("华文楷体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); | |||||
this.label2.Location = new System.Drawing.Point(100, 80); | |||||
this.label2.Name = "label2"; | |||||
this.label2.Size = new System.Drawing.Size(115, 23); | |||||
this.label2.TabIndex = 4; | |||||
this.label2.Text = "选择变量:"; | |||||
// | |||||
// label3 | |||||
// | |||||
this.label3.AutoSize = true; | |||||
this.label3.Font = new System.Drawing.Font("华文楷体", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); | |||||
this.label3.Location = new System.Drawing.Point(79, 120); | |||||
this.label3.Name = "label3"; | |||||
this.label3.Size = new System.Drawing.Size(136, 23); | |||||
this.label3.TabIndex = 5; | |||||
this.label3.Text = "设定变量值:"; | |||||
// | |||||
// textBox1 | |||||
// | |||||
this.textBox1.Location = new System.Drawing.Point(203, 120); | |||||
this.textBox1.Name = "textBox1"; | |||||
this.textBox1.Size = new System.Drawing.Size(121, 23); | |||||
this.textBox1.TabIndex = 6; | |||||
// | |||||
// Form1 | |||||
// | |||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F); | |||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |||||
this.ClientSize = new System.Drawing.Size(500, 263); | |||||
this.Controls.Add(this.textBox1); | |||||
this.Controls.Add(this.comboBox2); | |||||
this.Controls.Add(this.comboBox1); | |||||
this.Controls.Add(this.label3); | |||||
this.Controls.Add(this.label2); | |||||
this.Controls.Add(this.label1); | |||||
this.Controls.Add(this.button1); | |||||
this.Name = "Form1"; | |||||
this.Text = "Form1"; | |||||
this.ResumeLayout(false); | |||||
this.PerformLayout(); | |||||
} | |||||
#endregion | |||||
private Button button1; | |||||
private Label label1; | |||||
private ComboBox comboBox1; | |||||
private ComboBox comboBox2; | |||||
private Label label2; | |||||
private Label label3; | |||||
private TextBox textBox1; | |||||
} | |||||
} |
@@ -0,0 +1,74 @@ | |||||
using BPA.Helper; | |||||
using BPASmart.Model; | |||||
using BPA.Communication; | |||||
using Newtonsoft.Json; | |||||
namespace ComputerTestDemo | |||||
{ | |||||
public partial class Form1 : Form | |||||
{ | |||||
List<CommunicationModel> communicationModels = new List<CommunicationModel>(); | |||||
public Form1() | |||||
{ | |||||
InitializeComponent(); | |||||
textBox1.Enabled = false; | |||||
button1.Enabled = false; | |||||
Json<CommunicationPar>.Read(); | |||||
communicationModels = Json<CommunicationPar>.Data.CommunicationDevices.Where(p => p.DeviceName.Length > 0).ToList(); | |||||
communicationModels.ForEach(item => { comboBox1.Items.Add(item.DeviceName); }); | |||||
Task.Run(new Action(() => | |||||
{ | |||||
MqttInit(); | |||||
})); | |||||
} | |||||
MqttHelper mqttHelper = new MqttHelper(); | |||||
private void MqttInit() | |||||
{ | |||||
mqttHelper.Connect("admin", "fengyoufu067101!@#", "124.222.238.75", 61613, $"·Ö²¼Ê½ÉÏλ»ú:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); | |||||
mqttHelper.ConnectOk = new Action(() => | |||||
{ | |||||
this.Invoke(new Action(() => { textBox1.Enabled = true; button1.Enabled = true; })); | |||||
}); | |||||
} | |||||
private void Publish(PublishInfo publishInfo) | |||||
{ | |||||
mqttHelper.Publish("DistributedHostComputer/Control", JsonConvert.SerializeObject(publishInfo)); | |||||
} | |||||
private void button1_Click(object sender, EventArgs e) | |||||
{ | |||||
string DeviceName = comboBox1.Text.Trim(); | |||||
string VarName = comboBox2.Text.Trim(); | |||||
var resDevices = communicationModels.FirstOrDefault(p => p.DeviceName == DeviceName); | |||||
if (resDevices != null) | |||||
{ | |||||
var resVars = resDevices.VarTableModels.FirstOrDefault(p => p.VarName == VarName); | |||||
if (resVars != null) | |||||
{ | |||||
PublishInfo publishInfo = new PublishInfo(); | |||||
publishInfo.PublishModels.Add(new PublishModel() | |||||
{ | |||||
DataType = (EDataType)Enum.Parse(typeof(EDataType), resVars.DataType), | |||||
DeviceName = DeviceName, | |||||
RealAddress = resVars.RealAddress, | |||||
Value = textBox1.Text.Trim(), | |||||
}); | |||||
Publish(publishInfo); | |||||
} | |||||
} | |||||
} | |||||
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) | |||||
{ | |||||
string selectName = comboBox1.Text.Trim(); | |||||
var res = communicationModels.FirstOrDefault(p => p.DeviceName == selectName); | |||||
if (res != null) | |||||
{ | |||||
comboBox2.Items.Clear(); | |||||
res.VarTableModels.ToList()?.ForEach(item => { comboBox2.Items.Add(item.VarName); }); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,60 @@ | |||||
<root> | |||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||||
<xsd:element name="root" msdata:IsDataSet="true"> | |||||
<xsd:complexType> | |||||
<xsd:choice maxOccurs="unbounded"> | |||||
<xsd:element name="metadata"> | |||||
<xsd:complexType> | |||||
<xsd:sequence> | |||||
<xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||||
</xsd:sequence> | |||||
<xsd:attribute name="name" use="required" type="xsd:string" /> | |||||
<xsd:attribute name="type" type="xsd:string" /> | |||||
<xsd:attribute name="mimetype" type="xsd:string" /> | |||||
<xsd:attribute ref="xml:space" /> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
<xsd:element name="assembly"> | |||||
<xsd:complexType> | |||||
<xsd:attribute name="alias" type="xsd:string" /> | |||||
<xsd:attribute name="name" type="xsd:string" /> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
<xsd:element name="data"> | |||||
<xsd:complexType> | |||||
<xsd:sequence> | |||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||||
</xsd:sequence> | |||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||||
<xsd:attribute ref="xml:space" /> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
<xsd:element name="resheader"> | |||||
<xsd:complexType> | |||||
<xsd:sequence> | |||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||||
</xsd:sequence> | |||||
<xsd:attribute name="name" type="xsd:string" use="required" /> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
</xsd:choice> | |||||
</xsd:complexType> | |||||
</xsd:element> | |||||
</xsd:schema> | |||||
<resheader name="resmimetype"> | |||||
<value>text/microsoft-resx</value> | |||||
</resheader> | |||||
<resheader name="version"> | |||||
<value>2.0</value> | |||||
</resheader> | |||||
<resheader name="reader"> | |||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</resheader> | |||||
<resheader name="writer"> | |||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||||
</resheader> | |||||
</root> |
@@ -0,0 +1,17 @@ | |||||
namespace ComputerTestDemo | |||||
{ | |||||
internal static class Program | |||||
{ | |||||
/// <summary> | |||||
/// The main entry point for the application. | |||||
/// </summary> | |||||
[STAThread] | |||||
static void Main() | |||||
{ | |||||
// To customize application configuration such as set high DPI settings or default font, | |||||
// see https://aka.ms/applicationconfiguration. | |||||
ApplicationConfiguration.Initialize(); | |||||
Application.Run(new Form1()); | |||||
} | |||||
} | |||||
} |
@@ -164,7 +164,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmart.Model", "BPASmart. | |||||
EndProject | EndProject | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmart.Server", "BPASmart.Server\BPASmart.Server.csproj", "{F67FBFAC-6C80-466D-A596-1B9B10E885FC}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmart.Server", "BPASmart.Server\BPASmart.Server.csproj", "{F67FBFAC-6C80-466D-A596-1B9B10E885FC}" | ||||
EndProject | EndProject | ||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Communication", "Communication\Communication.csproj", "{1062F7C7-0117-413C-A45E-8F9B525FC036}" | |||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Communication", "Communication\Communication.csproj", "{1062F7C7-0117-413C-A45E-8F9B525FC036}" | |||||
EndProject | |||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComputerTestDemo", "ComputerTestDemo\ComputerTestDemo.csproj", "{8940F1E2-693D-407E-AD03-722718860609}" | |||||
EndProject | EndProject | ||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
@@ -1520,6 +1522,26 @@ Global | |||||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x64.Build.0 = Release|Any CPU | {1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x64.Build.0 = Release|Any CPU | ||||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x86.ActiveCfg = Release|Any CPU | {1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x86.ActiveCfg = Release|Any CPU | ||||
{1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x86.Build.0 = Release|Any CPU | {1062F7C7-0117-413C-A45E-8F9B525FC036}.Release|x86.Build.0 = Release|Any CPU | ||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|ARM.ActiveCfg = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|ARM.Build.0 = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|ARM64.ActiveCfg = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|ARM64.Build.0 = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|x64.ActiveCfg = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|x64.Build.0 = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|x86.ActiveCfg = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Debug|x86.Build.0 = Debug|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|ARM.ActiveCfg = Release|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|ARM.Build.0 = Release|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|ARM64.ActiveCfg = Release|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|ARM64.Build.0 = Release|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|x64.ActiveCfg = Release|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|x64.Build.0 = Release|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|x86.ActiveCfg = Release|Any CPU | |||||
{8940F1E2-693D-407E-AD03-722718860609}.Release|x86.Build.0 = Release|Any CPU | |||||
EndGlobalSection | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -1596,6 +1618,7 @@ Global | |||||
{5083C91F-B23E-445D-8B7F-AF87E636E847} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | {5083C91F-B23E-445D-8B7F-AF87E636E847} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | ||||
{F67FBFAC-6C80-466D-A596-1B9B10E885FC} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | {F67FBFAC-6C80-466D-A596-1B9B10E885FC} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | ||||
{1062F7C7-0117-413C-A45E-8F9B525FC036} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | {1062F7C7-0117-413C-A45E-8F9B525FC036} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | ||||
{8940F1E2-693D-407E-AD03-722718860609} = {CDC1E762-5E1D-4AE1-9DF2-B85761539086} | |||||
EndGlobalSection | EndGlobalSection | ||||
GlobalSection(ExtensibilityGlobals) = postSolution | GlobalSection(ExtensibilityGlobals) = postSolution | ||||
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} | SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} | ||||