123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- using System;
- using System.Collections.Generic;
- using S7.Net;
- using Newtonsoft.Json.Linq;
- using ProjectBase.Data.Logs;
- using ProjectBase.Data.Redis;
- using ProjectBase.Data.BaseDAL;
- using SIMDP.BLL;
- using SIMDP.Model;
- using ProjectBase.Util;
- using System.Timers;
- using System.Reflection;
- namespace SIMDP.Device
- {
- public class PlcS7Net : AbstractBaseDevice
- {
- #region 数据定义
- /// <summary>
- /// PLC对象
- /// </summary>
- protected Plc S7Plc;
- /// <summary>
- /// 数据节点字典 key-变量名称, value-节点信息
- /// </summary>
- protected Dictionary<string, S7NetDataPointInfo> allPoints = new Dictionary<string, S7NetDataPointInfo>();
- /// <summary>
- /// 监控节点列表
- /// </summary>
- protected List<S7NetDataPointInfo> monitorPoints = new List<S7NetDataPointInfo>();
- #endregion
- #region TYPE定义
- public class S7NetPlcConfig
- {
- public S7NetPlcConfig(string json)
- {
- JObject jObject = JObject.Parse(json);
- CPU = getCpuTypeByName((string)jObject["CPU"]);
- JToken token = jObject["IP"];
- if (token != null)
- IP = (string)token;
- token = jObject["Rack"];
- if (token != null)
- RACK = (short)token;
- token = jObject["Slot"];
- if (token != null)
- SLOT = (short)token;
- token = jObject["Timer"];
- if (token != null)
- TIMER = Convert.ToDouble(token.ToString());
- }
- public CpuType CPU { get; set; }
- public string IP { get; set; } = "192.168.0.1";
- public short RACK { get; set; } = 0;
- public short SLOT { get; set; } = 1;
- public double TIMER { get; set; } = 1000;
- CpuType getCpuTypeByName(string cpuName)
- {
- if (cpuName.Contains("1200"))
- return CpuType.S71200;
- else if (cpuName.Contains("1500"))
- return CpuType.S71500;
- else if (cpuName.Contains("200"))
- return CpuType.S7200;
- else if (cpuName.Contains("300"))
- return CpuType.S7300;
- else if (cpuName.Contains("400"))
- return CpuType.S7400;
- else
- return CpuType.S71500; // 默认为1500
- }
- }
- public class S7NetDataPointInfo
- {
- // 节点配置信息
- public MoDataPoint mo;
- // 节点属性
- public short DB { get; set; }
- public short ADDR { get; set; }
- public VarType TYPE { get; set; }
- public byte BIT { get; set; } = 0;
- // 节点值及动作定义
- public object value = null;
- public MethodInfo proc = null;
- public S7NetDataPointInfo(MoDataPoint _mo)
- {
- mo = _mo;
- JObject jObject = JObject.Parse(mo.DataPointSource);
- DB = Convert.ToInt16((string)jObject["DB"]);
- ADDR = Convert.ToInt16((string)jObject["ADDR"]);
- TYPE = getVarTypeByDataPointType(mo.DataPointType);
- JToken token = jObject["BIT"];
- if (token != null)
- BIT = Convert.ToByte(token.ToString());
- }
- VarType getVarTypeByDataPointType(long type)
- {
- if (type == 1)
- return VarType.Bit;
- else if (type == 2)
- return VarType.Byte;
- else if (type == 3)
- return VarType.Int;
- else if (type == 4)
- return VarType.Word;
- else if (type == 5)
- return VarType.DInt;
- else if (type == 6)
- return VarType.DWord;
- else if (type == 7)
- return VarType.Real;
- else if (type == 9)
- return VarType.String;
- else
- return VarType.Bit;
- }
- }
- #endregion
- #region 接口实现
- public override void Start(MoPlcInfo _plcInfo, List<MoDataPoint> _dataPoints)
- {
- plcInfo = _plcInfo;
- S7NetPlcConfig plcConfig = new S7NetPlcConfig(plcInfo.LinkConfig);
- S7Plc = new Plc(plcConfig.CPU, plcConfig.IP, plcConfig.RACK, plcConfig.SLOT);
- timer.Interval = plcConfig.TIMER;
- timer.Elapsed += timer_Elapsed;
- timer.AutoReset = false;
- // PLC未连接状态
- SetRedisPlcDisConnect();
- // 创建PLC数据点表
- CreateDataPointList(_dataPoints);
- // 初始化自定义函数
- actionStart();
- // 启动时尝试连接一次设备
- Connect();
- // 启动定时器
- timerStopped = false;
- timer.Start();
- }
- public override bool isConnected()
- {
- return S7Plc.IsConnected;
- }
- protected override bool Connect()
- {
- S7Plc.Open();
- SetRedisPlcConnected();
- LogHelper.log.Info("已连接到PLC:" + S7Plc.IP);
- return isConnected();
- }
- protected override void Disconnect()
- {
- if (S7Plc != null)
- S7Plc.Close();
- SetRedisPlcDisConnect();
- }
- void CreateDataPointList(List<MoDataPoint> dataPoints)
- {
- if (redis == null)
- redis = new RedisHelper();
- Type t = this.GetType();
- foreach (MoDataPoint dataPoint in dataPoints)
- {
- S7NetDataPointInfo dataPointInfo = new S7NetDataPointInfo(dataPoint);
- allPoints.Add(dataPoint.DataPointName, dataPointInfo);
- redis.SetString(dataPoint.DataPointId.ToString() + dataPoint.DataPointName, "");
- //if (BLLFactory<BlDataGroup>.Instance.IsSignalGroupById(dataPoint.DataPointGroupId))
- // 不再按照信号组类型区分是否为监控节点,只按照是否有执行逻辑
- if (dataPoint.DataProc.Trim() != "")
- {
- dataPointInfo.proc = t.GetMethod(dataPoint.DataProc);
- monitorPoints.Add(dataPointInfo);
- }
- }
- }
- #endregion
- #region 读写操作
- /// <summary>
- /// 读取节点数据
- /// </summary>
- public bool Read(string dataPointName, out object value)
- {
- value = null;
- if (!allPoints.ContainsKey(dataPointName))
- {
- return false;
- }
- S7NetDataPointInfo p = allPoints[dataPointName];
- return Read(p, out value);
- }
- public bool Read(S7NetDataPointInfo p, out object value)
- {
- switch (p.TYPE)
- {
- case VarType.Bit:
- value = Convert.ToBoolean(S7Plc.Read(DataType.DataBlock, p.DB, p.ADDR, p.TYPE, 1, p.BIT));
- break;
- case VarType.Byte:
- value = Convert.ToByte(S7Plc.Read(DataType.DataBlock, p.DB, p.ADDR, p.TYPE, 1));
- break;
- case VarType.Int:
- value = Convert.ToInt16(S7Plc.Read(DataType.DataBlock, p.DB, p.ADDR, p.TYPE, 1));
- break;
- case VarType.Word:
- value = Convert.ToUInt16(S7Plc.Read(DataType.DataBlock, p.DB, p.ADDR, p.TYPE, 1));
- break;
- case VarType.DInt:
- value = Convert.ToInt32(S7Plc.Read(DataType.DataBlock, p.DB, p.ADDR, p.TYPE, 1));
- break;
- case VarType.DWord:
- value = Convert.ToUInt32(S7Plc.Read(DataType.DataBlock, p.DB, p.ADDR, p.TYPE, 1));
- break;
- case VarType.Real:
- value = Convert.ToDouble(S7Plc.Read(DataType.DataBlock, p.DB, p.ADDR, p.TYPE, 1));
- break;
- case VarType.String:
- byte length = (byte)S7Plc.Read(DataType.DataBlock, p.DB, p.ADDR + 1, VarType.Byte, 1);
- value = S7Plc.Read(DataType.DataBlock, p.DB, p.ADDR + 2, p.TYPE, length).ToString();
- break;
- default:
- value = null;
- return false;
- }
- UpdataRedisDataPoint(p.mo, value.ToString());
- return true;
- }
- /// <summary>
- /// 写入节点数据
- /// </summary>
- public bool Write(string dataPointName, object value)
- {
- if (!allPoints.ContainsKey(dataPointName))
- {
- return false;
- }
- S7NetDataPointInfo p = allPoints[dataPointName];
- switch (p.TYPE)
- {
- case VarType.Bit:
- S7Plc.WriteBit(DataType.DataBlock, p.DB, p.ADDR, p.BIT, Convert.ToBoolean(value));
- break;
- case VarType.Byte:
- S7Plc.Write(DataType.DataBlock, p.DB, p.ADDR, Convert.ToByte(value));
- break;
- case VarType.Int:
- S7Plc.Write(DataType.DataBlock, p.DB, p.ADDR, Convert.ToInt16(value));
- break;
- case VarType.Word:
- S7Plc.Write(DataType.DataBlock, p.DB, p.ADDR, Convert.ToUInt16(value));
- break;
- case VarType.DInt:
- S7Plc.Write(DataType.DataBlock, p.DB, p.ADDR, Convert.ToInt32(value));
- break;
- case VarType.DWord:
- S7Plc.Write(DataType.DataBlock, p.DB, p.ADDR, Convert.ToUInt32(value));
- break;
- case VarType.Real:
- S7Plc.Write(DataType.DataBlock, p.DB, p.ADDR, Convert.ToDouble(value));
- break;
- case VarType.String:
- S7Plc.Write(DataType.DataBlock, p.DB, p.ADDR + 1, Convert.ToByte(value.ToString().Length));
- S7Plc.Write(DataType.DataBlock, p.DB, p.ADDR + 2, value.ToString());
- break;
- default:
- return false;
- }
- UpdataRedisDataPoint(p.mo, value.ToString());
- return true;
- }
- #endregion
- }
- }
|