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

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

这个功能能通过 plcgroup.json 文件加载后,动态修改
parent ceaf9a32
......@@ -14,16 +14,15 @@ namespace Misc
/// <summary>
/// 这个属性用于报警
/// </summary>
/// <param name="offIsError"></param>
public IsErrorAttribute(bool offIsError = false)
public IsErrorAttribute() //(bool offIsError = false)
{
OffIsError = offIsError;
//OffIsError = offIsError;
}
/// <summary>
/// 属性的值为false, 为报警状态
/// </summary>
public bool OffIsError { get; private set; }
//public bool OffIsError { get; private set; }
}
}
......@@ -110,14 +110,8 @@ namespace FLY.Modbus
/// <returns></returns>
public object ToPropertyObj(object plc_value)
{
if (type == REG_TYPE.BOOL)
{
return plc_value;
}
else
{
return RegTypeConverter.ToObject((UInt16[])plc_value, type, scale);
}
return RegTypeConverter.ToObject(plc_value, type, scale);
}
/// <summary>
/// PLC 对象(寄存器、线圈)转 PC 属性, 本地
......@@ -134,9 +128,6 @@ namespace FLY.Modbus
/// <returns>bool or UInt16[]</returns>
public object ToPLCObj(object value)
{
if (type == REG_TYPE.BOOL)
return value;
else
return RegTypeConverter.ToRegs(value, type, scale);
}
/// <summary>
......
......@@ -16,7 +16,7 @@ namespace FLY.Modbus
public class PLCDevice
{
[JsonConverter(typeof(IPEndPointJsonConverter))]
public IPEndPoint EP { get; set; }
public IPEndPoint EP;
}
public class PLCVariable
......@@ -24,31 +24,31 @@ namespace FLY.Modbus
/// <summary>
/// 设备序号
/// </summary>
public int DeviceIndex { get; set; }
public int DeviceIndex;
/// <summary>
/// 值为 0,1,3,4 ;对应modbus寄存器的区号
/// </summary>
public string Mode { get; set; }
public string Mode;
/// <summary>
/// 区号的地址
/// </summary>
public int Addr { get; set; }
public int Addr;
/// <summary>
/// 类型 只有 bool 才对应 bool, 其它数值类型 都转为 float
/// </summary>
public string Type { get; set; }
public string Type;
/// <summary>
/// 放大倍数
/// </summary>
public double Scale { get; set; }
public double Scale;
/// <summary>
/// 属性拥有者名称
/// </summary>
public string OwnerName { get; set; }
public string OwnerName;
/// <summary>
/// 属性名称
/// </summary>
public string PropertyName { get; set; }
public string PropertyName;
public override string ToString()
{
......@@ -59,15 +59,5 @@ namespace FLY.Modbus
public List<PLCDevice> Devices = new List<PLCDevice>();
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
{
/// <summary>
/// PLC寄存器 转 C# 类型数据
/// PLC寄存器 或线圈 转 C# 类型数据
/// </summary>
/// <param name="data">PLC 寄存器数据</param>
/// <param name="plc_value">PLC 寄存器数据 ushort[] 或 bool </param>
/// <param name="type">PLC 数据类型</param>
/// <param name="scale">PLC数据放大倍数</param>
/// <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)
{
//case REG_TYPE.BOOL:
......@@ -70,27 +81,25 @@ namespace FLY.Modbus
}
/// <summary>
/// C# 类型数据 转 PLC寄存器
/// C# 类型数据 转 PLC寄存器 或线圈
/// </summary>
/// <param name="value">C#中数值 只能是 float or bool</param>
/// <param name="type">PLC 数据类型</param>
/// <param name="scale">PLC数据放大倍数</param>
/// <returns></returns>
public static ushort[] ToRegs(object value, REG_TYPE type, double scale)
/// <returns>ushort[] or bool </returns>
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;
//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;
f = (float)(f / scale);
switch (type)
......@@ -130,6 +139,10 @@ namespace FLY.Modbus
(ushort)((bs[1] << 8) | bs[0]),
(ushort)((bs[3] << 8) | bs[2]) };
}
default:
{
throw new Exception("ToObject type=" + type + "不支持的类型");
}
}
return null;
}
......
......@@ -25,6 +25,7 @@ namespace FLY.OBJComponents.Server
/// 报警系统
/// </summary>
WarningSystem mWarning;
public byte ErrCode=0;
public ErrorConf(IPLCProxySystemService PLCos, WarningSystem mWarning, string plcName)
{
this.PLCos = PLCos;
......@@ -49,7 +50,7 @@ namespace FLY.OBJComponents.Server
}
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
List<ErrorInfo> error_property = new List<ErrorInfo>();
......@@ -59,18 +60,18 @@ namespace FLY.OBJComponents.Server
{
//肯定有,没有就让它出错!!!
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()
{
property = propertyInfo.Name,
msg = desp,
offIsError = offIsError,
code = code
//offIsError = offIsError,
code = ErrCode
};
error_property.Add(errorInfo);
code++;
ErrCode++;
}
}
obj_error.Add(sender, new ErrorAction()
......@@ -86,24 +87,6 @@ namespace FLY.OBJComponents.Server
/// </summary>
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)
{
obj.PropertyChanged += Obj_PropertyChanged_ForError;
......
......@@ -6,6 +6,8 @@ using System.Linq;
using System.Text;
using FLY.Modbus;
using System.Windows.Threading;
using System.IO;
using Newtonsoft.Json;
namespace FLY.OBJComponents.Server
{
......@@ -37,7 +39,7 @@ namespace FLY.OBJComponents.Server
List<Plan> planIDs = new List<Plan>();
public List<DataToRegs> DRMap = new List<DataToRegs>();
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>
/// 与PLC连接成功
......@@ -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()
{
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