Browse Source

add gold power supplier

chenkui 2 months ago
parent
commit
29c96242de

+ 3 - 0
Framework/Common/Common.csproj

@@ -258,13 +258,16 @@
     <Compile Include="Device\Galil\IGalilDevice.cs" />
     <Compile Include="Device\LinMot\LinMotDelegate.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierCommand.cs" />
+    <Compile Include="Device\PowerSupplier\IPowerSupplierDevice.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierDeviceConfigCfg.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierDevice.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierDeviceConfig.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierDeviceConfigManager.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierDeviceConfigManager_SerialPort.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierFlag.cs" />
+    <Compile Include="Device\PowerSupplier\PowerSupplierGoldModbusDevice.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierSerialPortModbusDevice.cs" />
+    <Compile Include="Device\PowerSupplier\PowerSupplierTcpGoldModbusMessage.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierTcpModbusMessage.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierMessage.cs" />
     <Compile Include="Device\PowerSupplier\PowerSupplierModbusDevice.cs" />

+ 119 - 0
Framework/Common/Device/PowerSupplier/IPowerSupplierDevice.cs

@@ -0,0 +1,119 @@
+using MECF.Framework.Common.CommonData.PowerSupplier;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MECF.Framework.Common.Device.PowerSupplier
+{
+    public interface IPowerSupplierDevice
+    {
+        /// <summary>
+        /// 连接状态
+        /// </summary>
+        bool Connected { get; }
+        /// <summary>
+        /// 启动
+        /// </summary>
+        void Start();
+        /// <summary>
+        /// 停止
+        /// </summary>
+        void Stop();
+        /// <summary>
+        /// 设置控制模式
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <param name="remoteControl"></param>
+        /// <returns></returns>
+        bool SetChannelPowerControl(byte channel, byte remoteControl);
+        /// <summary>
+        /// 获取当前电压电流
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        void GetChannelVoltageAndCurrent(byte channel);
+        /// <summary>
+        /// 获取通道输出开关控制
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        void GetChannelOutput(byte channel);
+        /// <summary>
+        /// 获取通道电流设置数值
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        void GetChannelCurrentSetting(byte channel);
+        /// <summary>
+        /// 设置通道输出开关控制
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <param name="enabled"></param>
+        bool SetChannelOutputSwitchControl(byte channel, bool enabled);
+        /// <summary>
+        /// 设置通道输出开关控制
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        void GetChannelPowerControl(byte channel);
+
+        /// <summary>
+        /// 设置通道输出开关控制
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <param name="enabled"></param>
+        bool SetCurrentValue( byte channel, int current);
+        /// <summary>
+        /// 启动步阶
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <param name="stepPeriodDatas"></param>
+        bool SetStepPeriod(byte channel, List<PowerSupplierStepPeriodData> stepPeriodDatas, int voltageScale, int currentScale);
+        /// <summary>
+        /// 启动步阶
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <param name="startStep"></param>
+        /// <param name="endStep"></param>
+        /// <param name="cycle"></param>
+        bool StartStepPeriod(byte channel, ushort startStep, ushort endStep, ushort cycle);
+        /// <summary>
+        /// 设置电源运行模式
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <param name="model"></param>
+        bool SetChannelPowerRunmodelControl(byte channel, byte model);
+        /// <summary>
+        /// 设置电源运行模式
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <param name="model"></param>
+        void GetChannelPowerRunModel(byte channel);
+        /// <summary>
+        /// 获取通道电源状态
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        bool SetChannelPowerStatus(byte channel, byte powerstatus);
+        /// <summary>
+        /// 获取通道电源状态
+        /// </summary>
+        /// <param name="name"></param>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        void GetChannelPowerStatus(byte channel);
+    }
+}

+ 2 - 0
Framework/Common/Device/PowerSupplier/PowerSupplierDeviceConfig.cs

@@ -32,6 +32,8 @@ namespace MECF.Framework.Common.Device.PowerSupplier
 
         [XmlAttribute(AttributeName = "RecvTimeout", Form = XmlSchemaForm.Unqualified, DataType = "int")]
         public int RecvTimeout { get; set; }
+        [XmlAttribute(AttributeName = "Type", Form = XmlSchemaForm.Unqualified, DataType = "int")]
+        public int Type { get; set; }
 
         [XmlElement(Type = typeof(PowerSupplierDevice), ElementName = "Device", IsNullable = false, Form = XmlSchemaForm.Qualified)]
         public List<PowerSupplierDevice> Devices { get { return _devices; } set { _devices = value; InvokePropertyChanged(nameof(Devices)); } }

+ 26 - 8
Framework/Common/Device/PowerSupplier/PowerSupplierDeviceConfigManager.cs

@@ -1,17 +1,20 @@
 using Aitex.Common.Util;
 using Aitex.Core.RT.ConfigCenter;
 using Aitex.Core.RT.DataCenter;
+using Aitex.Core.RT.Fsm;
 using Aitex.Core.RT.Log;
 using Aitex.Core.RT.SCCore;
 using Aitex.Core.Util;
 using MECF.Framework.Common.CommonData.PowerSupplier;
 using MECF.Framework.Common.Device.LinMot;
+using MECF.Framework.Common.Equipment;
 using MECF.Framework.Common.Layout;
 using MECF.Framework.Common.TwinCat;
 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows.Forms;
@@ -21,6 +24,12 @@ namespace MECF.Framework.Common.Device.PowerSupplier
     public class PowerSupplierDeviceConfigManager : Singleton<PowerSupplierDeviceConfigManager>
     {
         #region 常量
+        private const string NAME_SPACE = "MECF.Framework.Common.Device.PowerSupplier";
+        private Dictionary<int, string> _typePowerSupplier = new Dictionary<int,string>()
+        {
+            { 0,nameof(PowerSupplierModbusDevice) },
+            {1,nameof(PowerSupplierGoldModbusDevice) }
+        };
         #endregion
         #region 内部变量
         /// <summary>
@@ -30,7 +39,7 @@ namespace MECF.Framework.Common.Device.PowerSupplier
         /// <summary>
         /// Modbus通信对象字典(key-名称,value
         /// </summary>
-        private Dictionary<string, PowerSupplierModbusDevice> _nameModbusDeviceDic = new Dictionary<string, PowerSupplierModbusDevice>();
+        private Dictionary<string, IPowerSupplierDevice> _nameModbusDeviceDic = new Dictionary<string, IPowerSupplierDevice>();
         /// <summary>
         /// 模块变量注册事件字典
         /// </summary>
@@ -62,9 +71,18 @@ namespace MECF.Framework.Common.Device.PowerSupplier
                 {
                     foreach (PowerSupplierDeviceConfig config in cfg.PowerSupplierDeviceConfigs)
                     {
-                        PowerSupplierModbusDevice modbusDevice = new PowerSupplierModbusDevice(config.Name, config.IpAddress, config.Port);
-                        modbusDevice.ReceiveTimeout = config.RecvTimeout;
-                        modbusDevice.SendTimeout = config.SendTimeout;
+                        IPowerSupplierDevice modbusDevice;
+                        if (_typePowerSupplier.ContainsKey(config.Type))
+                        {
+                            string deviceClass = $"{NAME_SPACE}.{_typePowerSupplier[config.Type]}";
+                            Assembly assembly = Assembly.GetExecutingAssembly();
+                            Type type = assembly.GetType(deviceClass);
+                            modbusDevice = (IPowerSupplierDevice)Activator.CreateInstance(type,config.Name,config.IpAddress,config.Port,config.RecvTimeout,config.SendTimeout);
+                        }
+                        else
+                        {
+                            modbusDevice = new PowerSupplierModbusDevice(config.Name, config.IpAddress, config.Port,config.RecvTimeout,config.SendTimeout);
+                        }
                         InitialDeviceConfig(config, modbusDevice);
                     }
                 }
@@ -113,7 +131,7 @@ namespace MECF.Framework.Common.Device.PowerSupplier
         /// 初始化设备
         /// </summary>
         /// <param name="config"></param>
-        private void InitialDeviceConfig(PowerSupplierDeviceConfig config,PowerSupplierModbusDevice modbusDevice)
+        private void InitialDeviceConfig(PowerSupplierDeviceConfig config,IPowerSupplierDevice modbusDevice)
         {
             foreach (PowerSupplierDevice item in config.Devices)
             {
@@ -203,7 +221,7 @@ namespace MECF.Framework.Common.Device.PowerSupplier
         /// <param name="name"></param>
         /// <param name="channel"></param>
         /// <param name="enabled"></param>
-        public bool SetChannelCurrent(string name, byte channel, ushort current)
+        public bool SetChannelCurrent(string name, byte channel, int current)
         {
             if (_nameModbusDeviceDic.ContainsKey(name))
             {
@@ -217,11 +235,11 @@ namespace MECF.Framework.Common.Device.PowerSupplier
         /// <param name="name"></param>
         /// <param name="channel"></param>
         /// <param name="stepPeriodDatas"></param>
-        public bool SetStepPeriod(string name,byte channel,List<PowerSupplierStepPeriodData> stepPeriodDatas,int scale)
+        public bool SetStepPeriod(string name,byte channel,List<PowerSupplierStepPeriodData> stepPeriodDatas,int voltageScale,int currentScale)
         {
             if (_nameModbusDeviceDic.ContainsKey(name))
             {
-                return _nameModbusDeviceDic[name].SetStepPeriod(channel, stepPeriodDatas,scale);
+                return _nameModbusDeviceDic[name].SetStepPeriod(channel, stepPeriodDatas,voltageScale,currentScale);
             }
             return false;
         }

+ 395 - 0
Framework/Common/Device/PowerSupplier/PowerSupplierGoldModbusDevice.cs

@@ -0,0 +1,395 @@
+using Aitex.Core.RT.Log;
+using Aitex.Core.Util;
+using DocumentFormat.OpenXml.InkML;
+using MECF.Framework.Common.CommonData.PowerSupplier;
+using MECF.Framework.Common.Communications;
+using MECF.Framework.Common.Net;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MECF.Framework.Common.Device.PowerSupplier
+{
+    public class PowerSupplierGoldModbusDevice : JetMessageTcpClient<PowerSupplierTcpGoldModbusMessage, PowerSupplierCommand>,IPowerSupplierDevice
+    {
+        #region 常量 
+        private const short CURRENT_SETTING_ADDRESS = 0x6102;
+        private const short OUTPUT_CONTROL_ADDRESS = 0x0110;
+        private const short STEP_PERIOD_ADDRESS = 0x77D0;
+        private const short STEP_PERIOD_START_ADDRESS = 0x7C50;
+        private const short VOLTAGE_OUTPUT_ADDRESS = 0x0201;
+        private const short POWER_CONTROL_ADDRESS = 0x0113;
+        private const short POWER_RUN_MODEL_ADDRESS = 0x0111;
+        /// <summary>
+        /// 电源状态(00-cv输出,01-cc输出)
+        /// </summary>
+        private const short POWER_STATUS_ADDRESS = 0x0200;
+        private const string SET_POINT = "SetPoint";
+        private const string CURRENT = "Current";
+        private const string VOLTAGE = "Voltage";
+        private const string ENABLED = "Enabled";
+        private const string POWER_STATUS = "PowerStatus";
+        private const string POWER_CONTROL = "PowerControl";
+        private const string POWER_RUN_MODEL = "PowerRunModel";
+        /// <summary>
+        /// 步阶数据数量
+        /// </summary>
+        private const int STEP_PERIOD_LENGTH = 12;
+        #endregion
+        #region 内部变量
+        private string _name;
+        private string _lastErrorMsg = "";
+        private bool _isFirstConnected = false;
+        #endregion
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="ip"></param>
+        /// <param name="port"></param>
+        public PowerSupplierGoldModbusDevice(string name, string ip, int port,int receiveTimeout,int sendTimeout) : base(ip, port)
+        {
+            ReceiveTimeout = receiveTimeout;
+            SendTimeout = sendTimeout;
+            ReconnectInterval = 3000;
+            ConnectTimeout = 1000;
+            _name = name;
+        }
+        /// <summary>
+        /// 连接
+        /// </summary>
+        /// <returns></returns>
+        public void Start()
+        {
+            Connect();
+            if (!_isFirstConnected)
+            {
+                _isFirstConnected = true;
+            }
+        }
+        /// <summary>
+        /// 设置通道输出开关控制
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <param name="currentValue"></param>
+        /// <returns></returns>
+        public bool SetChannelOutputSwitchControl(byte channel, bool enabled)
+        {
+            PowerSupplierCommand command = new PowerSupplierCommand();
+            command.Channel = channel;
+            command.CommandCode = 0x06;
+            command.Address = (ushort)(OUTPUT_CONTROL_ADDRESS);
+            command.Datas = new ushort[] { enabled ? (ushort)01 : (ushort)00 };
+            return SetOperation(command);
+        }
+
+        /// <summary>
+        /// 设置电源控制
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <param name="currentValue"></param>
+        /// <returns></returns>
+        public bool SetChannelPowerControl(byte channel, byte remoteControl)
+        {
+            PowerSupplierCommand command = new PowerSupplierCommand();
+            command.Channel = channel;
+            command.CommandCode = 0x06;
+            command.Address = (ushort)(POWER_CONTROL_ADDRESS);
+            command.Datas = new ushort[] { remoteControl };
+            return SetOperation(command);
+        }
+        /// <summary>
+        /// 设置电源运行模式
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <param name="currentValue"></param>
+        /// <returns></returns>
+        public bool SetChannelPowerRunmodelControl(byte channel, byte model)
+        {
+            PowerSupplierCommand command = new PowerSupplierCommand();
+            command.Channel = channel;
+            command.CommandCode = 0x06;
+            command.Address = (ushort)(POWER_RUN_MODEL_ADDRESS);
+            command.Datas = new ushort[] { model };
+            return SetOperation(command);
+        }
+        /// <summary>
+        /// 设置步阶数据
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <param name="stepDatas"></param>
+        public bool SetStepPeriod(byte channel, List<PowerSupplierStepPeriodData> stepDatas, int voltageScale,int currentScale)
+        {
+            PowerSupplierCommand command = new PowerSupplierCommand();
+            command.Channel = channel;
+            command.CommandCode = 0x10;
+            command.Address = (ushort)STEP_PERIOD_ADDRESS;
+            command.RegisterCount = (ushort)(STEP_PERIOD_LENGTH * stepDatas.Count);
+            command.Datas = new ushort[STEP_PERIOD_LENGTH * stepDatas.Count];
+            for (int i = 0; i < stepDatas.Count; i++)
+            {
+                PowerSupplierStepPeriodData data = stepDatas[i];
+                command.Datas[0 + STEP_PERIOD_LENGTH * i] = (ushort)(data.Voltage * voltageScale/0xffff);
+                command.Datas[1 + STEP_PERIOD_LENGTH * i] = (ushort)(data.Voltage * voltageScale %0xffff);
+                command.Datas[2 + STEP_PERIOD_LENGTH * i] = (ushort)(Math.Round(stepDatas[i].Current * currentScale, 0)/0xffff);
+                command.Datas[3 + STEP_PERIOD_LENGTH * i] = (ushort)(Math.Round(stepDatas[i].Current * currentScale, 0) % 0xffff);
+                command.Datas[4 + STEP_PERIOD_LENGTH * i] = 0;
+                command.Datas[5 + STEP_PERIOD_LENGTH * i] = stepDatas[i].Hour;
+                command.Datas[6 + STEP_PERIOD_LENGTH * i] = 0;
+                command.Datas[7 + STEP_PERIOD_LENGTH * i] = stepDatas[i].Minute;
+                command.Datas[8 + STEP_PERIOD_LENGTH * i] = 0;
+                command.Datas[9 + STEP_PERIOD_LENGTH * i] = stepDatas[i].Second;
+                command.Datas[10 + STEP_PERIOD_LENGTH * i] = 0;
+                command.Datas[11 + STEP_PERIOD_LENGTH * i] = stepDatas[i].Microsecond;
+            }
+            return SetOperation(command);
+        }
+
+
+        /// <summary>
+        /// 启动步阶
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <param name="startStep"></param>
+        /// <param name="endStep"></param>
+        /// <param name="cycle"></param>
+        public bool StartStepPeriod(byte channel, ushort startStep, ushort endStep, ushort cycle)
+        {
+            PowerSupplierCommand command = new PowerSupplierCommand();
+            command.Channel = channel;
+            command.CommandCode = 0x10;
+            command.Address = (ushort)STEP_PERIOD_START_ADDRESS;
+            command.RegisterCount = 6;
+            command.Datas = new ushort[6] {0,startStep, 0,endStep,0,cycle };
+            return SetOperation(command);
+        }
+
+        /// <summary>
+        /// 设置电流
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <param name="currentValue"></param>
+        /// <returns></returns>
+        public bool SetCurrentValue(byte channel, int currentValue)
+        {
+            PowerSupplierCommand command = new PowerSupplierCommand();
+            command.Channel = channel;
+            command.CommandCode = 0x10;
+            command.Address = (ushort)(CURRENT_SETTING_ADDRESS);
+            command.RegisterCount = 4;//2N N-寄存器地址数据
+            ushort[] ushorts = new ushort[2];
+            ushorts[0] = (ushort)(currentValue / 0xFFFF);//高位
+            ushorts[1] = (ushort)(currentValue % 0xFFFF);//低位
+            command.Datas = ushorts;
+            return SetOperation(command);
+        }
+
+        /// <summary>
+        /// 设置电源状态
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <param name="currentValue"></param>
+        /// <returns></returns>
+        public bool SetChannelPowerStatus(byte channel, byte powerStatus)
+        {
+            PowerSupplierCommand command = new PowerSupplierCommand();
+            command.Channel = channel;
+            command.CommandCode = 0x06;
+            command.Address = (ushort)(POWER_STATUS_ADDRESS);
+            command.Datas = new ushort[] { powerStatus };
+            return SetOperation(command);
+        }
+        /// <summary>
+        /// 获取通道输出开关控制
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        public void GetChannelOutput(byte channel)
+        {
+            PowerSupplierCommand applyCommand = new PowerSupplierCommand();
+            applyCommand.Channel = channel;
+            applyCommand.CommandCode = 0x03;
+            applyCommand.Address = (ushort)(OUTPUT_CONTROL_ADDRESS);
+            applyCommand.RegisterCount = 1;
+            applyCommand.Variables.Add(ENABLED, (0, 1));
+            ApplyDataOperation(applyCommand);
+        }
+        /// <summary>
+        /// 获取通道电源控制
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        public void GetChannelPowerControl(byte channel)
+        {
+            PowerSupplierCommand applyCommand = new PowerSupplierCommand();
+            applyCommand.Channel = channel;
+            applyCommand.CommandCode = 0x03;
+            applyCommand.Address = (ushort)(POWER_CONTROL_ADDRESS);
+            applyCommand.RegisterCount = 1;
+            applyCommand.Variables.Add(POWER_CONTROL, (0, 1));
+            ApplyDataOperation(applyCommand);
+        }
+        /// <summary>
+        /// 获取通道电流设置数值
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        public void GetChannelCurrentSetting(byte channel)
+        {
+            PowerSupplierCommand applyCommand = new PowerSupplierCommand();
+            applyCommand.Channel = channel;
+            applyCommand.CommandCode = 0x03;
+            applyCommand.Address = (ushort)(CURRENT_SETTING_ADDRESS);
+            applyCommand.RegisterCount = 2;
+            applyCommand.Variables.Add(SET_POINT, (0, 2));
+            ApplyDataOperation(applyCommand);
+        }
+
+        /// <summary>
+        /// 获取电源状态设置数值
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        public void GetChannelPowerStatus(byte channel)
+        {
+            PowerSupplierCommand applyCommand = new PowerSupplierCommand();
+            applyCommand.Channel = channel;
+            applyCommand.CommandCode = 0x03;
+            applyCommand.Address = (ushort)(POWER_STATUS_ADDRESS);
+            applyCommand.RegisterCount = 1;
+            applyCommand.Variables.Add(POWER_STATUS, (0, 1));
+            ApplyDataOperation(applyCommand);
+        }
+
+        /// <summary>
+        /// 获取电源运行模式
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        public void GetChannelPowerRunModel(byte channel)
+        {
+            PowerSupplierCommand applyCommand = new PowerSupplierCommand();
+            applyCommand.Channel = channel;
+            applyCommand.CommandCode = 0x03;
+            applyCommand.Address = (ushort)(POWER_RUN_MODEL_ADDRESS);
+            applyCommand.RegisterCount = 1;
+            applyCommand.Variables.Add(POWER_RUN_MODEL, (0, 1));
+            ApplyDataOperation(applyCommand);
+        }
+        /// <summary>
+        /// 申请电压和电流数值
+        /// </summary>
+        /// <param name="channel"></param>
+        /// <returns></returns>
+        public void GetChannelVoltageAndCurrent(byte channel)
+        {
+            PowerSupplierCommand applyCommand = new PowerSupplierCommand();
+            applyCommand.Channel = channel;
+            applyCommand.CommandCode = 0x03;
+            applyCommand.Address = (ushort)(VOLTAGE_OUTPUT_ADDRESS);
+            applyCommand.RegisterCount = 4;
+            applyCommand.Variables.Add(VOLTAGE, (0, 2));
+            applyCommand.Variables.Add(CURRENT, (2, 2));
+            ApplyDataOperation(applyCommand);
+        }
+        /// <summary>
+        /// 设置操作
+        /// </summary>
+        /// <param name="command"></param>
+        /// <returns></returns>
+        private bool SetOperation(PowerSupplierCommand command)
+        {
+            if (Connected)
+            {
+                NetResult netResult = SetData(command);
+                if (!netResult.IsSuccess)
+                {
+                    WriteErrMsg($"write write {command.Address.ToString("X2")} value {command.Datas[0]} failed,{netResult.Message}");
+                    return false;
+                }
+                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>
+        /// <param name="command"></param>
+        private void ApplyDataOperation(PowerSupplierCommand command)
+        {
+            if (!Connected)
+            {
+                NetResult connectResult = Connect();
+                if (!connectResult.IsSuccess)
+                {
+                    WriteErrMsg("connect failed");
+                    return;
+                }
+            }
+            NetResult<PowerSupplierCommand> netResult = ApplyData(command);
+            if (!netResult.IsSuccess)
+            {
+                WriteErrMsg($"apply {command.Address.ToString("X2")} failed,{netResult.Message}");
+                return;
+            }
+            if (netResult.Data.Datas != null)
+            {
+                Dictionary<string, (int, int)> dictionary = command.Variables;
+                List<string> keys = dictionary.Keys.ToList();
+                foreach (string item in keys)
+                {
+                    var result = dictionary[item];
+                    if (item == ENABLED)
+                    {
+                        PowerSupplierDeviceConfigManager.Instance.UpdateModuleVariable(_name, command.Channel, ENABLED, netResult.Data.Datas[result.Item1] == 0x01);
+                    }
+                    else
+                    {
+                        if (result.Item2 == 1)
+                        {
+                            PowerSupplierDeviceConfigManager.Instance.UpdateModuleVariable(_name, command.Channel, item, netResult.Data.Datas[result.Item1]);
+                        }
+                        else if (result.Item2 == 2)
+                        {
+                            int value = netResult.Data.Datas[result.Item1] * 0xFFFF + netResult.Data.Datas[result.Item1 + 1];
+                            PowerSupplierDeviceConfigManager.Instance.UpdateModuleVariable(_name, command.Channel, item, value);
+                        }
+                    }
+                }
+            }
+        }
+        /// <summary>
+        /// 写错误日志
+        /// </summary>
+        /// <param name="msg"></param>
+        private void WriteErrMsg(string msg)
+        {
+            if (msg != _lastErrorMsg)
+            {
+                _lastErrorMsg = msg;
+
+                LOG.WriteLog(eEvent.ERR_POWERSUPPLIER, _name, msg);
+            }
+        }
+    }
+}

+ 9 - 9
Framework/Common/Device/PowerSupplier/PowerSupplierModbusDevice.cs

@@ -13,7 +13,7 @@ using System.Threading.Tasks;
 
 namespace MECF.Framework.Common.Device.PowerSupplier
 {
-    public class PowerSupplierModbusDevice : JetMessageTcpClient<PowerSupplierTcpModbusMessage, PowerSupplierCommand>
+    public class PowerSupplierModbusDevice : JetMessageTcpClient<PowerSupplierTcpModbusMessage, PowerSupplierCommand>,IPowerSupplierDevice
     {
         #region 常量 
         private const short CURRENT_SETTING_ADDRESS = 0x0101;
@@ -49,10 +49,10 @@ namespace MECF.Framework.Common.Device.PowerSupplier
         /// </summary>
         /// <param name="ip"></param>
         /// <param name="port"></param>
-        public PowerSupplierModbusDevice(string name, string ip, int port) : base(ip, port)
+        public PowerSupplierModbusDevice(string name, string ip, int port,int receiveTimeout,int sendTimeout) : base(ip, port)
         {
-            ReceiveTimeout = 1000;
-            SendTimeout = 1000;
+            ReceiveTimeout = receiveTimeout;
+            SendTimeout = sendTimeout;
             ReconnectInterval = 3000;
             ConnectTimeout = 1000;
             _name = name;
@@ -120,7 +120,7 @@ namespace MECF.Framework.Common.Device.PowerSupplier
         /// </summary>
         /// <param name="channel"></param>
         /// <param name="stepDatas"></param>
-        public bool SetStepPeriod(byte channel, List<PowerSupplierStepPeriodData> stepDatas, int scale)
+        public bool SetStepPeriod(byte channel, List<PowerSupplierStepPeriodData> stepDatas, int voltageScale, int currentScale)
         {
             PowerSupplierCommand command = new PowerSupplierCommand();
             command.Channel = channel;
@@ -131,8 +131,8 @@ namespace MECF.Framework.Common.Device.PowerSupplier
             for (int i = 0; i < stepDatas.Count; i++)
             {
                 PowerSupplierStepPeriodData data = stepDatas[i];
-                command.Datas[0 + STEP_PERIOD_LENGTH * i] = (ushort)(data.Voltage * 1000);
-                command.Datas[1 + STEP_PERIOD_LENGTH * i] = (ushort)Math.Round(stepDatas[i].Current * scale, 0);
+                command.Datas[0 + STEP_PERIOD_LENGTH * i] = (ushort)(data.Voltage * voltageScale);
+                command.Datas[1 + STEP_PERIOD_LENGTH * i] = (ushort)Math.Round(stepDatas[i].Current * currentScale, 0);
                 command.Datas[2 + STEP_PERIOD_LENGTH * i] = stepDatas[i].Hour;
                 command.Datas[3 + STEP_PERIOD_LENGTH * i] = stepDatas[i].Minute;
                 command.Datas[4 + STEP_PERIOD_LENGTH * i] = stepDatas[i].Second;
@@ -164,13 +164,13 @@ namespace MECF.Framework.Common.Device.PowerSupplier
         /// <param name="channel"></param>
         /// <param name="currentValue"></param>
         /// <returns></returns>
-        public bool SetCurrentValue(byte channel, ushort currentValue)
+        public bool SetCurrentValue(byte channel, int currentValue)
         {
             PowerSupplierCommand command = new PowerSupplierCommand();
             command.Channel = channel;
             command.CommandCode = 0x06;
             command.Address = (ushort)(CURRENT_SETTING_ADDRESS);
-            command.Datas = new ushort[] { currentValue };
+            command.Datas = new ushort[] { (ushort)currentValue };
             return SetOperation(command);
         }
 

+ 189 - 0
Framework/Common/Device/PowerSupplier/PowerSupplierTcpGoldModbusMessage.cs

@@ -0,0 +1,189 @@
+using Aitex.Core.Utilities;
+using log4net.Core;
+using MECF.Framework.Common.Net;
+using MECF.Framework.Common.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Remoting.Messaging;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace MECF.Framework.Common.Device.PowerSupplier
+{
+    public class PowerSupplierTcpGoldModbusMessage : INetMessage<PowerSupplierCommand>
+    {
+        #region 属性
+        public int ProtocolHeadBytesLength { get; set; } = 6;
+
+        public int ErrorCode { get; set; }
+
+        public string ErrorMsg { get; set; }
+
+        public byte[] HeadBytes { get; set; }
+        public byte[] ContentBytes { get; set; }
+        public byte[] SendBytes { get; set; }
+        #endregion
+
+        #region 内部变量
+        IByteTransform byteTransform=new BigEndianByteTransformBase();
+        #endregion
+
+        public bool CheckDataLegal()
+        {
+            //第二个字节高位为0x80,设备报错
+            if((ContentBytes[1]&0x80)==0x80)
+            {
+                ErrorCode = (int)NetErrorCode.DeviceError;
+                ErrorMsg = GetDeviceMessage(ContentBytes[2]);
+                return false;
+            }
+            //数据长度不一致
+            if (ContentBytes[1] == 0x03)
+            {
+                byte contentLength = ContentBytes[2];
+                if (ContentBytes.Length - 3 != contentLength)
+                {
+                    ErrorCode = (int)NetErrorCode.InvalidData;
+                    ErrorMsg = EnumUtil.GetEnumDescription(NetErrorCode.InvalidData);
+                    return false;
+                }
+            }
+            return true;
+        }
+        /// <summary>
+        /// 设备错误信息
+        /// </summary>
+        /// <returns></returns>
+        private string GetDeviceMessage(byte deviceErrorCode)
+        {
+            switch(deviceErrorCode)
+            {
+                case 0x01:
+                    return "Invalid Function";
+                case 0x02:
+                    return "Invalid Address";
+                case 0x03:
+                    return "Invalid Data";
+                case 0x04:
+                    return "Slave Device Error";
+                case 0x05:
+                    return "Error Confirm";
+                case 0x06:
+                    return "Slave Device Busy";
+                default:
+                    return "Unkown Error Code";
+            }
+        }
+
+        public bool CheckHeadBytesLegal()
+        {
+            //地址与指令同时一致
+            return SendBytes[0] == HeadBytes[0] && SendBytes[1] == HeadBytes[1] && HeadBytes[2] == 0x00 && HeadBytes[3]==0x00;
+        }
+
+
+        public bool ConfirmResponseResult()
+        {
+            //指令码与发送指令码一致
+            if (HeadBytes[1] == SendBytes[1])
+            {
+                return true;
+            }
+            return false;
+        }
+
+        public PowerSupplierCommand Decode() 
+        {
+            PowerSupplierCommand command = new PowerSupplierCommand();
+            if (ContentBytes[1] == 0x03)
+            {
+                int registerCount = ContentBytes[2] / 2;
+                command.Datas = byteTransform.TransUInt16(ContentBytes, 3, registerCount);
+            }
+            return command;
+        }
+
+        public int GetContentLengthByHeadBytes()
+        {
+            return byteTransform.TransInt16(HeadBytes, 4);
+        }
+
+        public int GetHeadBytesIdentity()
+        {
+            return byteTransform.TransInt16(HeadBytes, 0);
+        }
+
+        public byte[] Code(PowerSupplierCommand data) 
+        {
+            byte[] byt = null; 
+            //读取指令
+            if(data.CommandCode==0x03)
+            {
+                byt= new byte[12];
+                //事务处理标识
+                Array.Copy(PowerSupplierFlag.Instance.GenerateDataFlagBuffer(byteTransform),0, byt, 0, 2);
+                //固定码0x0000
+                byt[2] = 0x00;
+                byt[3] = 0x00;
+                //数据长度
+                byt[4] = 0x00;
+                byt[5] = 0x06;
+                //通道
+                byt[6] = data.Channel;
+                //指令
+                byt[7] = data.CommandCode;
+                Array.Copy(byteTransform.GetBytes(data.Address), 0, byt, 8, 2);
+                Array.Copy(byteTransform.GetBytes(data.RegisterCount), 0, byt, 10, 2);
+            }
+            //写单个寄存器地址
+            else if(data.CommandCode==0x06)
+            {
+                byt = new byte[12];
+                //事务处理标识
+                Array.Copy(PowerSupplierFlag.Instance.GenerateDataFlagBuffer(byteTransform), 0, byt, 0, 2);
+                //固定码0x0000
+                byt[2] = 0x00;
+                byt[3] = 0x00;
+                //数据长度
+                byt[4] = 0x00;
+                byt[5] = 0x06;
+                //通道
+                byt[6] = data.Channel;
+                //指令
+                byt[7] = data.CommandCode;
+                Array.Copy(byteTransform.GetBytes(data.Address), 0, byt, 8, 2);
+                Array.Copy(byteTransform.GetBytes(data.Datas[0]), 0, byt, 10, 2);
+            }
+            else if(data.CommandCode==0x10)
+            {
+                byt = new byte[6+7+2*data.Datas.Length];
+                //事务处理标识
+                Array.Copy(PowerSupplierFlag.Instance.GenerateDataFlagBuffer(byteTransform), 0, byt, 0, 2);
+                //固定码0x0000
+                byt[2] = 0x00;
+                byt[3] = 0x00;
+                //数据长度
+                byt[4] = 0x00;
+                byt[5] = 0x06;
+                //通道
+                byt[6] = data.Channel;
+                //指令
+                byt[7] = data.CommandCode;
+                Array.Copy(byteTransform.GetBytes(data.Address), 0, byt, 8, 2);
+                Array.Copy(byteTransform.GetBytes(data.RegisterCount), 0, byt, 10, 2);
+                byt[12] = (byte)(2 * data.Datas.Length);
+                for (int i = 0; i < data.Datas.Length; i++)
+                {
+                    Array.Copy(byteTransform.GetBytes(data.Datas[i]), 0, byt, 13+i*2, 2);
+                }
+            }
+            return byt;
+        }
+
+        public void SetProtocolHeadBytesLength()
+        {            
+        }
+    }
+}

+ 10 - 15
Framework/Common/Utilities/PeriodicJob.cs

@@ -11,7 +11,6 @@ namespace Aitex.Core.Util
     {
         Thread _thread;
         int _interval;
-        DeviceTimer _elapseTimer;
         Func<bool> _func;
         
         CancellationTokenSource _cancelFlag = new CancellationTokenSource();        //for quit thread 
@@ -37,8 +36,6 @@ namespace Aitex.Core.Util
             _interval = interval;
             _func = func;
 
-            _elapseTimer = new DeviceTimer();
-
             if (isStartNow)
                 Start();
         }
@@ -56,8 +53,6 @@ namespace Aitex.Core.Util
                     return;
 
                 _thread.Start(this);
-
-                _elapseTimer.Start(0);
             }
         }
 
@@ -122,24 +117,24 @@ namespace Aitex.Core.Util
 
         void Run()
         {
-            try
+            while (!_cancelFlag.IsCancellationRequested)
             {
-                while (!_cancelFlag.IsCancellationRequested)
+                try
                 {
-
                     _waitFlag.WaitOne();
-
-                    _elapseTimer.Start(0);
+                    DateTime now = DateTime.Now;
 
                     if (!_func())
                         break;
-                    _sleepFlag.WaitOne(Math.Max(_interval - (int)_elapseTimer.GetElapseTime(), 30));
+                    int elapseTime = (int)DateTime.Now.Subtract(now).TotalMilliseconds;
+                    _sleepFlag.WaitOne(Math.Max(_interval - elapseTime, 30));
+                }
+                catch (Exception ex)
+                {
+                    LOG.WriteExeption(ex);
                 }
             }
-            catch (Exception ex)
-            {
-                LOG.WriteExeption(ex);
-            }
+            
         }
     }
 }