Commit fa1cdf1e authored by 潘栩锋's avatar 潘栩锋 🚴

PLC 线圈报警只能 On时报警。 修改ModbusMapper BOOL 放大 功能,scale=-1,使BOOL反向。 实现Off时报警。

这个功能能通过 plcgroup.json 文件加载后,动态修改
parent ceaf9a32
...@@ -14,16 +14,15 @@ namespace Misc ...@@ -14,16 +14,15 @@ namespace Misc
/// <summary> /// <summary>
/// 这个属性用于报警 /// 这个属性用于报警
/// </summary> /// </summary>
/// <param name="offIsError"></param> public IsErrorAttribute() //(bool offIsError = false)
public IsErrorAttribute(bool offIsError = false)
{ {
OffIsError = offIsError; //OffIsError = offIsError;
} }
/// <summary> /// <summary>
/// 属性的值为false, 为报警状态 /// 属性的值为false, 为报警状态
/// </summary> /// </summary>
public bool OffIsError { get; private set; } //public bool OffIsError { get; private set; }
} }
} }
...@@ -110,14 +110,8 @@ namespace FLY.Modbus ...@@ -110,14 +110,8 @@ namespace FLY.Modbus
/// <returns></returns> /// <returns></returns>
public object ToPropertyObj(object plc_value) public object ToPropertyObj(object plc_value)
{ {
if (type == REG_TYPE.BOOL) return RegTypeConverter.ToObject(plc_value, type, scale);
{
return plc_value;
}
else
{
return RegTypeConverter.ToObject((UInt16[])plc_value, type, scale);
}
} }
/// <summary> /// <summary>
/// PLC 对象(寄存器、线圈)转 PC 属性, 本地 /// PLC 对象(寄存器、线圈)转 PC 属性, 本地
...@@ -134,9 +128,6 @@ namespace FLY.Modbus ...@@ -134,9 +128,6 @@ namespace FLY.Modbus
/// <returns>bool or UInt16[]</returns> /// <returns>bool or UInt16[]</returns>
public object ToPLCObj(object value) public object ToPLCObj(object value)
{ {
if (type == REG_TYPE.BOOL)
return value;
else
return RegTypeConverter.ToRegs(value, type, scale); return RegTypeConverter.ToRegs(value, type, scale);
} }
/// <summary> /// <summary>
......
...@@ -16,7 +16,7 @@ namespace FLY.Modbus ...@@ -16,7 +16,7 @@ namespace FLY.Modbus
public class PLCDevice public class PLCDevice
{ {
[JsonConverter(typeof(IPEndPointJsonConverter))] [JsonConverter(typeof(IPEndPointJsonConverter))]
public IPEndPoint EP { get; set; } public IPEndPoint EP;
} }
public class PLCVariable public class PLCVariable
...@@ -24,31 +24,31 @@ namespace FLY.Modbus ...@@ -24,31 +24,31 @@ namespace FLY.Modbus
/// <summary> /// <summary>
/// 设备序号 /// 设备序号
/// </summary> /// </summary>
public int DeviceIndex { get; set; } public int DeviceIndex;
/// <summary> /// <summary>
/// 值为 0,1,3,4 ;对应modbus寄存器的区号 /// 值为 0,1,3,4 ;对应modbus寄存器的区号
/// </summary> /// </summary>
public string Mode { get; set; } public string Mode;
/// <summary> /// <summary>
/// 区号的地址 /// 区号的地址
/// </summary> /// </summary>
public int Addr { get; set; } public int Addr;
/// <summary> /// <summary>
/// 类型 只有 bool 才对应 bool, 其它数值类型 都转为 float /// 类型 只有 bool 才对应 bool, 其它数值类型 都转为 float
/// </summary> /// </summary>
public string Type { get; set; } public string Type;
/// <summary> /// <summary>
/// 放大倍数 /// 放大倍数
/// </summary> /// </summary>
public double Scale { get; set; } public double Scale;
/// <summary> /// <summary>
/// 属性拥有者名称 /// 属性拥有者名称
/// </summary> /// </summary>
public string OwnerName { get; set; } public string OwnerName;
/// <summary> /// <summary>
/// 属性名称 /// 属性名称
/// </summary> /// </summary>
public string PropertyName { get; set; } public string PropertyName;
public override string ToString() public override string ToString()
{ {
...@@ -59,15 +59,5 @@ namespace FLY.Modbus ...@@ -59,15 +59,5 @@ namespace FLY.Modbus
public List<PLCDevice> Devices = new List<PLCDevice>(); public List<PLCDevice> Devices = new List<PLCDevice>();
public List<PLCVariable> Variables = new List<PLCVariable>(); public List<PLCVariable> Variables = new List<PLCVariable>();
static PLCGroup()
{
Misc.SaveToXmlHepler.Regist(typeof(PLCDevice));
Misc.SaveToXmlHepler.Regist(typeof(PLCVariable));
}
public void Load(string filepath)
{
Misc.SaveToXmlHepler.Load(filepath, this);
}
} }
} }
...@@ -12,14 +12,25 @@ namespace FLY.Modbus ...@@ -12,14 +12,25 @@ namespace FLY.Modbus
{ {
/// <summary> /// <summary>
/// PLC寄存器 转 C# 类型数据 /// PLC寄存器 或线圈 转 C# 类型数据
/// </summary> /// </summary>
/// <param name="data">PLC 寄存器数据</param> /// <param name="plc_value">PLC 寄存器数据 ushort[] 或 bool </param>
/// <param name="type">PLC 数据类型</param> /// <param name="type">PLC 数据类型</param>
/// <param name="scale">PLC数据放大倍数</param> /// <param name="scale">PLC数据放大倍数</param>
/// <returns></returns> /// <returns></returns>
public static object ToObject(ushort[] data, REG_TYPE type, double scale) public static object ToObject(object plc_value, REG_TYPE type, double scale)
{ {
if(type == REG_TYPE.BOOL)
{
var v = (bool)plc_value;
if (scale < 0)
return !v;
else
return v;
}
ushort[] data = (ushort[])plc_value;
switch (type) switch (type)
{ {
//case REG_TYPE.BOOL: //case REG_TYPE.BOOL:
...@@ -70,27 +81,25 @@ namespace FLY.Modbus ...@@ -70,27 +81,25 @@ namespace FLY.Modbus
} }
/// <summary> /// <summary>
/// C# 类型数据 转 PLC寄存器 /// C# 类型数据 转 PLC寄存器 或线圈
/// </summary> /// </summary>
/// <param name="value">C#中数值 只能是 float or bool</param> /// <param name="value">C#中数值 只能是 float or bool</param>
/// <param name="type">PLC 数据类型</param> /// <param name="type">PLC 数据类型</param>
/// <param name="scale">PLC数据放大倍数</param> /// <param name="scale">PLC数据放大倍数</param>
/// <returns></returns> /// <returns>ushort[] or bool </returns>
public static ushort[] ToRegs(object value, REG_TYPE type, double scale) public static object ToRegs(object value, REG_TYPE type, double scale)
{
if (type == REG_TYPE.BOOL)
{ {
bool v = (bool)value;
if (scale < 0)
return !v;
else
return v;
}
byte[] bs; byte[] bs;
//if (type == REG_TYPE.BOOL)
//{
// bool v = (bool)value;
// if (v)
// {
// return new ushort[1] { 1 };
// }
// else
// {
// return new ushort[1] { 0 };
// }
//}
float f = (float)value; float f = (float)value;
f = (float)(f / scale); f = (float)(f / scale);
switch (type) switch (type)
...@@ -130,6 +139,10 @@ namespace FLY.Modbus ...@@ -130,6 +139,10 @@ namespace FLY.Modbus
(ushort)((bs[1] << 8) | bs[0]), (ushort)((bs[1] << 8) | bs[0]),
(ushort)((bs[3] << 8) | bs[2]) }; (ushort)((bs[3] << 8) | bs[2]) };
} }
default:
{
throw new Exception("ToObject type=" + type + "不支持的类型");
}
} }
return null; return null;
} }
......
...@@ -25,6 +25,7 @@ namespace FLY.OBJComponents.Server ...@@ -25,6 +25,7 @@ namespace FLY.OBJComponents.Server
/// 报警系统 /// 报警系统
/// </summary> /// </summary>
WarningSystem mWarning; WarningSystem mWarning;
public byte ErrCode=0;
public ErrorConf(IPLCProxySystemService PLCos, WarningSystem mWarning, string plcName) public ErrorConf(IPLCProxySystemService PLCos, WarningSystem mWarning, string plcName)
{ {
this.PLCos = PLCos; this.PLCos = PLCos;
...@@ -49,7 +50,7 @@ namespace FLY.OBJComponents.Server ...@@ -49,7 +50,7 @@ namespace FLY.OBJComponents.Server
} }
Dictionary<INotifyPropertyChanged, ErrorAction> obj_error = new Dictionary<INotifyPropertyChanged, ErrorAction>(); Dictionary<INotifyPropertyChanged, ErrorAction> obj_error = new Dictionary<INotifyPropertyChanged, ErrorAction>();
public void AddErrorAction(INotifyPropertyChanged sender, ref byte code, ErrorAction.ErrorHandler errorHandler = null, object state = null) public void AddErrorAction(INotifyPropertyChanged sender, ErrorAction.ErrorHandler errorHandler = null, object state = null)
{ {
//反射找出全部是报警的property //反射找出全部是报警的property
List<ErrorInfo> error_property = new List<ErrorInfo>(); List<ErrorInfo> error_property = new List<ErrorInfo>();
...@@ -59,18 +60,18 @@ namespace FLY.OBJComponents.Server ...@@ -59,18 +60,18 @@ namespace FLY.OBJComponents.Server
{ {
//肯定有,没有就让它出错!!! //肯定有,没有就让它出错!!!
string desp = (propertyInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).First() as DescriptionAttribute).Description; string desp = (propertyInfo.GetCustomAttributes(typeof(DescriptionAttribute), false).First() as DescriptionAttribute).Description;
bool offIsError = (propertyInfo.GetCustomAttributes(typeof(IsErrorAttribute), false).First() as IsErrorAttribute).OffIsError; //bool offIsError = (propertyInfo.GetCustomAttributes(typeof(IsErrorAttribute), false).First() as IsErrorAttribute).OffIsError;
ErrorInfo errorInfo = new ErrorInfo() ErrorInfo errorInfo = new ErrorInfo()
{ {
property = propertyInfo.Name, property = propertyInfo.Name,
msg = desp, msg = desp,
offIsError = offIsError, //offIsError = offIsError,
code = code code = ErrCode
}; };
error_property.Add(errorInfo); error_property.Add(errorInfo);
code++; ErrCode++;
} }
} }
obj_error.Add(sender, new ErrorAction() obj_error.Add(sender, new ErrorAction()
...@@ -86,24 +87,6 @@ namespace FLY.OBJComponents.Server ...@@ -86,24 +87,6 @@ namespace FLY.OBJComponents.Server
/// </summary> /// </summary>
public void InitError() public void InitError()
{ {
//byte code = 0;
////反射找出全部是报警的property
//AddErrorAction(
// Accessory,
// ref code);
//AddErrorAction(
// Items[0],
// ref code,
// (ref string description, object state) => { description = "内" + description; }
// );
//AddErrorAction(
// Items[1],
// ref code,
// (ref string description, object state) => { description = "外" + description; }
// );
foreach (var obj in obj_error.Keys) foreach (var obj in obj_error.Keys)
{ {
obj.PropertyChanged += Obj_PropertyChanged_ForError; obj.PropertyChanged += Obj_PropertyChanged_ForError;
......
...@@ -6,6 +6,8 @@ using System.Linq; ...@@ -6,6 +6,8 @@ using System.Linq;
using System.Text; using System.Text;
using FLY.Modbus; using FLY.Modbus;
using System.Windows.Threading; using System.Windows.Threading;
using System.IO;
using Newtonsoft.Json;
namespace FLY.OBJComponents.Server namespace FLY.OBJComponents.Server
{ {
...@@ -37,7 +39,7 @@ namespace FLY.OBJComponents.Server ...@@ -37,7 +39,7 @@ namespace FLY.OBJComponents.Server
List<Plan> planIDs = new List<Plan>(); List<Plan> planIDs = new List<Plan>();
public List<DataToRegs> DRMap = new List<DataToRegs>(); public List<DataToRegs> DRMap = new List<DataToRegs>();
public List<Modbus.WithThread.ModbusMapper_Client> PLCs = new List<Modbus.WithThread.ModbusMapper_Client>(); public List<Modbus.WithThread.ModbusMapper_Client> PLCs = new List<Modbus.WithThread.ModbusMapper_Client>();
public Dictionary<string, INotifyPropertyChanged> ObjNames { get; } = new Dictionary<string, INotifyPropertyChanged>(); public Dictionary<string, INotifyPropertyChanged> ObjNames { get; private set; } = new Dictionary<string, INotifyPropertyChanged>();
/// <summary> /// <summary>
/// 与PLC连接成功 /// 与PLC连接成功
...@@ -51,6 +53,55 @@ namespace FLY.OBJComponents.Server ...@@ -51,6 +53,55 @@ namespace FLY.OBJComponents.Server
} }
public void AddConfigFile(
string configfile,
Func<PLCGroup,Dictionary<string,INotifyPropertyChanged>> addObjNames)
{
PLCGroup plcgroup = new PLCGroup();
string json = File.ReadAllText(configfile);
JsonConvert.PopulateObject(json, plcgroup);
foreach (PLCGroup.PLCDevice device in plcgroup.Devices)
{
var plc = new Modbus.WithThread.ModbusMapper_Client(device.EP);
this.PLCs.Add(plc);
}
var objnames = addObjNames(plcgroup);
this.ObjNames = objnames;
foreach (PLCGroup.PLCVariable var in plcgroup.Variables)
{
if (var.DeviceIndex < 0 || var.DeviceIndex >= this.PLCs.Count)
continue;
List<DataToRegs> drs = this.DRMap;
var plc = this.PLCs[var.DeviceIndex];
var reg_type = ModbusMapper.TranslateToREG_TYPE(var.Type);
if (reg_type == REG_TYPE.Unknown)
{
throw new Exception($"DeviceIndex = {var.DeviceIndex} var.Addr={var.Addr} var.Type={var.Type} 不能转换为 C#类型");
}
DataToRegs dr = plc.MapDataToRegs(
ModbusMapper.TranslateToPLCAddressArea(var.Mode),
var.Addr,
reg_type,
var.Scale,
this.ObjNames[var.OwnerName],
var.PropertyName);
if (dr != null)
drs.Add(dr);
}
foreach (var plc in this.PLCs)
plc.Build();
}
/// <summary>
/// PLC 更新计划服务初始化
/// </summary>
public void Init() public void Init()
{ {
foreach (var plc in PLCs) foreach (var plc in PLCs)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment