123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- using Aitex.Core.RT.Log;
- using Aitex.Core.Util;
- using DocumentFormat.OpenXml.Wordprocessing;
- using MECF.Framework.Common.Device.PowerSupplier;
- using MECF.Framework.Common.Net;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace MECF.Framework.Common.Device.Festo
- {
- public class FestoModbusDevice : JetMessageTcpClient<FestoMessage, FestoCommand>
- {
- #region 内部变量
- /// <summary>
- /// 名称
- /// </summary>
- private string _name;
- /// <summary>
- /// 上一次错误信息
- /// </summary>
- private string _lastErrorMsg = "";
- /// <summary>
- /// do的数量
- /// </summary>
- private ushort _addressCount = 6;
- /// <summary>
- /// di开始地址
- /// </summary>
- private ushort _diStartAddress = 45395;
- /// <summary>
- /// 通道
- /// </summary>
- private byte _channel = 1;
- /// <summary>
- /// IP地址
- /// </summary>
- private string _ip = "";
- /// <summary>
- /// 端口号
- /// </summary>
- private int _port = 502;
- /// <summary>
- /// 定时器
- /// </summary>
- private PeriodicJob _periodicJob;
- /// <summary>
- /// 共享锁
- /// </summary>
- private object _locker = new object();
- /// <summary>
- /// 共享锁时长
- /// </summary>
- private int _lockerTime = 2000;
- #endregion
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="ip"></param>
- /// <param name="port"></param>
- public FestoModbusDevice(string name, string ip, int port,ushort diStartAddress,byte channel) : base(ip, port)
- {
- ReceiveTimeout = 1000;
- SendTimeout = 1000;
- ConnectTimeout = 1000;
- _name = name;
- _diStartAddress=diStartAddress;
- _ip = ip;
- _port = port;
- _channel = channel;
- _periodicJob = new PeriodicJob(200, OnTimer, $"festo {name} timer", false,true);
- }
- /// <summary>
- /// 定时器执行
- /// </summary>
- /// <returns></returns>
- private bool OnTimer()
- {
- if(Monitor.TryEnter(_locker, _lockerTime))
- {
- ApplyAllDatas();
- Monitor.Exit(_locker);
- }
- return true;
- }
- /// <summary>
- /// 更新地址数量
- /// </summary>
- /// <param name="addressCount"></param>
- public void InitializeAddressCount(ushort addressCount)
- {
- _addressCount = addressCount;
- NetResult result = Connect();
- if (result.IsSuccess)
- {
- ApplyAllDatas();
- LOG.WriteLog(eEvent.INFO_FESTO, _name, $"connect {_ip}:{_port} success");
- }
- else
- {
- LOG.WriteLog(eEvent.INFO_FESTO, _name, $"connect {_ip}:{_port} failed");
- }
- _periodicJob.Start();
- }
- /// <summary>
- /// 设置Festo数值
- /// </summary>
- /// <param name="address"></param>
- /// <param name="value"></param>
- /// <returns></returns>
- public bool SetFestoValue(ushort address,byte value)
- {
- FestoCommand command = new FestoCommand();
- command.Channel = _channel;
- command.Address=address;
- command.CommandCode = 0x06;
- command.Datas = new byte[1] { value };
- if (Monitor.TryEnter(_locker, _lockerTime))
- {
- bool result= SetOperation(command);
- Monitor.Exit(_locker);
- return result;
- }
- else
- {
- WriteErrMsg($"Write apply locker over {_lockerTime}");
- return false;
- }
- }
- /// <summary>
- /// 设置操作
- /// </summary>
- /// <param name="command"></param>
- /// <returns></returns>
- private bool SetOperation(FestoCommand command)
- {
- if (Connected)
- {
- NetResult netResult = SetData(command);
- if (!netResult.IsSuccess)
- {
- WriteErrMsg($"write {command.Address.ToString("X2")} value {command.Datas[0]} failed,{netResult.Message}");
- return false;
- }
- else
- {
- LOG.WriteLog(eEvent.INFO_FESTO, _name, $"write {command.Address.ToString("X2")} value {command.Datas[0]} success");
- }
- return true;
- }
- else
- {
- NetResult netResult = Connect();
- if (netResult.IsSuccess)
- {
- netResult = SetData(command);
- if (!netResult.IsSuccess)
- {
- WriteErrMsg($"write {command.Address.ToString("X2")} value {command.Datas[0]} failed,{netResult.Message}");
- return false;
- }
- return true;
- }
- else
- {
- WriteErrMsg("connect failed");
- return false;
- }
- }
- }
- /// <summary>
- /// 申请所有数据
- /// </summary>
- public void ApplyAllDatas()
- {
- FestoCommand command = new FestoCommand();
- command.Address = _diStartAddress;
- command.RegisterCount = (ushort)(_addressCount*2);
- command.CommandCode = 0x03;
- command.Channel = _channel;
- ApplyDataOperation(command);
- }
- /// <summary>
- /// 申请数据操作
- /// </summary>
- /// <param name="command"></param>
- private void ApplyDataOperation(FestoCommand command)
- {
- if (!Connected)
- {
- NetResult connectResult = Connect();
- if (!connectResult.IsSuccess)
- {
- WriteErrMsg("connect failed");
- return;
- }
- }
- NetResult<FestoCommand> netResult = ApplyData(command);
- if (!netResult.IsSuccess)
- {
- WriteErrMsg($"apply {command.Address.ToString("X2")} failed,{netResult.Message}");
- return;
- }
- if (netResult.Data.Datas != null)
- {
- //bit0--高8位,bit1-低8位,bit2-下一地址高8位,bit3--下一地址低8位,只取bit1
- byte[] bytes = new byte[_addressCount];
- for(int i = 0; i < netResult.Data.Datas.Length; i += 4)
- {
- if (i + 1 < netResult.Data.Datas.Length&&i/4<_addressCount)
- {
- byte data = netResult.Data.Datas[i + 1];
- bytes[i / 4] = data;
- }
- }
- FestoControllerCfgManager.Instance.UpdateFestoData(_name, bytes);
- }
- }
- /// <summary>
- /// 写错误日志
- /// </summary>
- /// <param name="msg"></param>
- private void WriteErrMsg(string msg)
- {
- if (msg != _lastErrorMsg)
- {
- _lastErrorMsg = msg;
- LOG.WriteLog(eEvent.ERR_FESTO, _name, msg);
- }
- }
- }
- }
|