汇川 PLC Modbus 协议通讯封装

汇川 PLC Modbus 协议通讯

封装实体类代码

using System.Net.NetworkInformation;
using System.Net.Sockets;
 public abstract class PLCBase
 {
     /// <summary>
     /// 互斥锁
     /// </summary>
     protected Mutex mutex = new Mutex();

     public bool IsConnect { get; set; } = false;

     /// <summary>
     /// IP地址
     /// </summary>
     protected string IP { get; set; } = "127.0.0.1";


     /// <summary>
     /// 端口
     /// </summary>
     protected UInt16 Port { get; set; } = 502;

     public enum EValueType { _BOOL, _INT16, _INT32, _INT64, _FLOAT, _DOUBLE, _STRING, _UINT16, _UINT32, _UINT64, _UNKNOW };

     public Socket SocketClient
     {
         get
         {
             if (_socket == null)
             {
                 _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { SendTimeout = 300, ReceiveTimeout = 1000 };
                 return _socket;
             }

             if (_socket.Connected == false)
             {
                 _socket.Close();
                 _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { SendTimeout = 300, ReceiveTimeout = 1000 };
             }

             return _socket;
         }
     }

     private Socket _socket;


     //public static Socket SocketClient
     //{
     //    get
     //    {
     //        --断开自动重新创建连接
     //        if (!_SocketClient.Connected)
     //        {
     //            _SocketClient.Close();
     //            _SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     //            _SocketClient.Connect(new IPEndPoint(IPAddress.Parse("IP地址"), _port)); //配置服务器IP与端口
     //            return _SocketClient;
     //        }
     //        return _SocketClient;
     //    }
     //}

     public bool Connect()
     {
         try
         {
             if (new System.Net.NetworkInformation.Ping().Send(IP, 1000).Status != IPStatus.Success)
                 return false;

             if (!Connect(IP, Port))
                 return false;

             IsConnect = true;
             return true;
         }
         catch 
         {
             IsConnect = false;
             return false;
         }
     }


     public bool Connect(string ip, UInt16 port)
     {
         try { IPAddress.Parse(ip); }
         catch { return false; }

         SocketClient.Connect(IPAddress.Parse(ip), port);

         return SocketClient.Connected;
     }


     public void Connect(Socket socket, string host, int port, TimeSpan timeout)
     {
         AsyncConnect(socket, (s, a, o) => s.BeginConnect(host, port, a, o), timeout);
     }

     /// <summary>
     /// Connects the specified socket.
     /// </summary>
     /// <param name="socket">The socket.</param>
     /// <param name="addresses">The addresses.</param>
     /// <param name="port">The port.</param>
     /// <param name="timeout">The timeout.</param>
     public void Connect(Socket socket, IPAddress addresses, int port, TimeSpan timeout)
     {
         AsyncConnect(socket, (s, a, o) => s.BeginConnect(addresses, port, a, o), timeout);
     }

     /// <summary>
     /// Asyncs the connect.
     /// </summary>
     /// <param name="socket">The socket.</param>
     /// <param name="connect">The connect.</param>
     /// <param name="timeout">The timeout.</param>
     private void AsyncConnect(Socket socket, Func<Socket, AsyncCallback, object, IAsyncResult> connect, TimeSpan timeout)
     {
         var asyncResult = connect(socket, null, null);
         if (!asyncResult.AsyncWaitHandle.WaitOne(timeout))
         {
             try
             {
                 socket.EndConnect(asyncResult);
             }
             catch (SocketException)
             { }
             catch (ObjectDisposedException)
             { }
         }
     }

     public void DisConnect()
     {
         IsConnect = false;
         SocketClient.Disconnect(true);
     }


     public static byte[] FormatConversion(byte[] bytes)
     {
         for (int j = 0; j * 2 + 1 < bytes.Length; j++)
         {
             byte temp = bytes[2 * j];
             bytes[2 * j] = bytes[2 * j + 1];
             bytes[2 * j + 1] = temp;
         }
         return bytes;
     }


 }
using System.Net.Sockets;
public interface IPLCBase
{


    Socket SocketClient { get; }


    bool Connect();

    void DisConnect();
    List<bool> ReadBools(string addr, UInt16 count);

    bool ReadBool(string addr);
    Int16 ReadInt16(string addr);

    List<Int16> ReadInt16s(string addr, UInt16 count);


    List<byte> ReadAllByte(string addr, UInt16 count = 65535);


    UInt16 ReadUInt16(string addr);

    List<UInt16> ReadUInt16s(string addr, UInt16 count);

    string ReadString(string addr, UInt16 count, bool stringFormate = true);
    double ReadDouble(string addr);

    List<double> ReadDoubles(string addr, UInt16 count);

    Int32 ReadInt32(string addr);

    List<Int32> ReadInt32s(string addr, UInt16 count);
    UInt32 ReadUInt32(string addr);
    List<UInt32> ReadUInt32s(string addr, UInt16 count);

    UInt64 ReadUInt64(string addr);

    List<UInt64> ReadUInt64s(string addr, UInt16 count);

    Int64 ReadInt64(string addr);
    List<Int64> ReadInt64s(string addr, UInt16 count);

    float ReadFloat(string addr);

    List<float> ReadFloats(string addr, UInt16 count);
    bool WriteBool(string addr, bool value);
    bool WriteBools(string addr, List<bool> value);
    bool WriteInt16(string addr, Int16 value);
    bool WriteInt16s(string addr, List<Int16> value);
    bool WriteUInt16(string addr, UInt16 value);
    bool WriteUInt16s(string addr, List<UInt16> value);


    bool WriteInt32(string addr, Int32 value);
    bool WriteInt32s(string addr, List<Int32> value);
    bool WriteUInt32(string addr, UInt32 value);
    bool WriteUInt32s(string addr, List<UInt32> value);

    bool WriteInt64(string addr, Int64 value);
    bool WriteInt64s(string addr, List<Int64> value);
    bool WriteUInt64(string addr, UInt64 value);
    bool WriteUInt64s(string addr, List<UInt64> value);

    bool WriteDouble(string addr, double value);
    bool WriteDoubles(string addr, List<double> value);


    bool WriteFloat(string addr, float value);
    bool WriteFloats(string addr, List<float> value);


    bool WriteString(string addr, string value);
}
public class IPLC
{
    private bool isConnect = false;
    public bool IsConnect { get { return this.isConnect; } set { this.isConnect = value; } }
    public string ErrorMsg { get; set; }

    public IPLCBase _iPLC;

    private IPLC()
    {
        //IsConnect = Connect();
    }


    public void DisConnect()
    {
        //  _iPLC.DisConnect();
        //  this.IsConnect = false;
    }

    private static byte[] obj = new byte[0];
    private static IPLC instance;
    public static IPLC Instance
    {
        get
        {
            if (instance == null)
            {
                lock (obj)
                {
                    if (instance == null)
                    {
                        instance = new IPLC();
                    }
                }
            }

            return instance;
        }
    }

    private static IPLC writer;
    public static IPLC Writer
    {
        get
        {
            if (writer == null)
            {
                lock (obj)
                {
                    if (writer == null)
                    {
                        writer = new IPLC();
                    }
                }
            }

            return writer;
        }
    }

    public bool Connect()
    {
        try
        {
            //_iPLC.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { SendTimeout = 300, ReceiveTimeout = 1000, };
            IsConnect = _iPLC.Connect();
            return IsConnect;
        }
        catch (Exception ex)
        {
            ErrorMsg = ex.Message;
            IsConnect = false;
            return IsConnect;
        }
    }

    public string ReadValue(string addr, EValueType valueType)
    {
        // 不可读string
        string result = string.Empty;

        //if (!IsConnect) return (T)result;

        switch (valueType)
        {
            case EValueType._BOOL:
                {
                    result = Convert.ToInt16(ReadBool(addr)).ToString();
                    break;
                }

            case EValueType._INT16:
                {
                    result = ReadInt16(addr).ToString();
                    break;
                }
            case EValueType._INT32:
                {
                    result = ReadInt32(addr).ToString();
                    break;
                }

            case EValueType._INT64:
                {
                    result = ReadInt64(addr).ToString();
                    break;
                }

            case EValueType._FLOAT:
                {
                    result = ReadFloat(addr).ToString();
                    break;
                }

            case EValueType._DOUBLE:
                {
                    result = ReadDouble(addr).ToString();
                    break;
                }

            default:
                break;
        }

        return result;
    }

    public bool ReadBool(string addr)
    {
        if (!IsConnect) return false;
        return _iPLC.ReadBool(addr);
    }

    public short ReadInt16(string addr)
    {
        if (!IsConnect) return (short)0;
        return (short)_iPLC.ReadInt16(addr);
    }


    public int ReadInt32(string addr)
    {
        if (!IsConnect) return 0;
        return _iPLC.ReadInt32(addr);
    }

    public long ReadInt64(string addr)
    {
        if (!IsConnect) return (long)0;
        return _iPLC.ReadInt64(addr);
    }

    public float ReadFloat(string addr)
    {
        if (!IsConnect) return 0;
        return _iPLC.ReadFloat(addr);
    }

    public double ReadDouble(string addr)
    {
        if (!IsConnect) return 0;
        return _iPLC.ReadDouble(addr);
    }

    public List<bool> ReadBool(string addr, ushort length)
    {
        if (!IsConnect) return new List<bool>();
        return _iPLC.ReadBools(addr, length);
    }

    public List<short> ReadInt16(string addr, ushort length)
    {
        if (!IsConnect) return new List<short>();
        return _iPLC.ReadInt16s(addr, length);
    }

    public List<ushort> ReadUInt16(string addr, ushort length)
    {
        if (!IsConnect) return new List<ushort>();
        return _iPLC.ReadUInt16s(addr, length);
    }

    public List<byte> ReadAllByte(string addr, ushort length)
    {
        if (!IsConnect) return new List<byte>();
        return _iPLC.ReadAllByte(addr, length);
    }



    public List<int> ReadInt32(string addr, ushort length)
    {
        if (!IsConnect) return new List<int>();
        return _iPLC.ReadInt32s(addr, length);
    }

    public List<uint> ReadUInt32(string addr, ushort length)
    {
        if (!IsConnect) return new List<uint>();
        return _iPLC.ReadUInt32s(addr, length);
    }


    public List<long> ReadInt64(string addr, ushort length)
    {
        if (!IsConnect) return new List<long>();
        return _iPLC.ReadInt64s(addr, length);
    }
    public List<ulong> ReadUInt64(string addr, ushort length)
    {
        if (!IsConnect) return new List<ulong>();
        return _iPLC.ReadUInt64s(addr, length);
    }

    public List<float> ReadFloat(string addr, ushort length)
    {
        if (!IsConnect) return new List<float>();
        return _iPLC.ReadFloats(addr, length);
    }

    public List<double> ReadDouble(string addr, ushort length)
    {
        if (!IsConnect)
            return new List<double>();
        return _iPLC.ReadDoubles(addr, length);
    }

    public string ReadString(string addr, ushort length)
    {
        if (!IsConnect) return "";
        //string str = _iPLC.ReadString(addr, length);
        //char[] chars = str.ToArray();
        //for (int i = 0; 2 * i < chars.Length; i++)
        //{
        //    char temp = chars[2 * i];
        //    chars[2 * i] = chars[2 * i + 1];
        //    chars[2 * i + 1] = temp;
        //}
        //return new string(chars);
        return _iPLC.ReadString(addr, length);
    }

    public bool WriteBool(string addr, bool value)
    {
        // 江门调试阶段,屏蔽写操作

        if (!IsConnect) return false;
        return _iPLC.WriteBool(addr, value);
    }

    public bool WriteInt16(string addr, short value)
    {
        // 江门调试阶段,屏蔽写操作

        if (!IsConnect) return false;
        return _iPLC.WriteInt16(addr, value);
    }

    public bool WriteUInt16(string addr, ushort value)
    {
        // 江门调试阶段,屏蔽写操作

        if (!IsConnect) return false;
        return _iPLC.WriteUInt16(addr, value);
    }

    public bool WriteInt32(string addr, int value)
    {
        // 江门调试阶段,屏蔽写操作

        if (!IsConnect) return false;
        return _iPLC.WriteInt32(addr, value);
    }

    public bool WriteUInt32(string addr, uint value)
    {
        // 江门调试阶段,屏蔽写操作

        if (!IsConnect) return false;
        return _iPLC.WriteUInt32(addr, value);
    }

    public bool WriteInt64(string addr, long value)
    {
        if (!IsConnect) return false;
        return _iPLC.WriteInt64(addr, value);
    }

    public bool WriteUInt64(string addr, ulong value)
    {

        if (!IsConnect) return false;
        return _iPLC.WriteUInt64(addr, value);
    }

    public bool WriteFloat(string addr, float value)
    {
        if (!IsConnect) return false;
        return _iPLC.WriteFloat(addr, value);
    }

    public bool WriteDouble(string addr, double value)
    {

        if (!IsConnect) return false;
        return _iPLC.WriteDouble(addr, value);
    }

    public bool WriteString(string addr, string value)
    {
        if (!IsConnect) return false;
        return _iPLC.WriteString(addr, value);
    }

    public bool WriteValue(string addr, EValueType valueType, string inputVal)
    {
        bool result = false;

        if (!IsConnect) return result;


        switch (valueType)
        {
            case EValueType._BOOL:
                {
                    result = _iPLC.WriteBool(addr, Convert.ToBoolean(inputVal));
                    break;
                }

            case EValueType._INT16:
                {
                    result = _iPLC.WriteInt16(addr, Convert.ToInt16(inputVal));
                    break;
                }
            case EValueType._INT32:
                {
                    result = _iPLC.WriteInt32(addr, Convert.ToInt32(inputVal));
                    break;
                }

            case EValueType._INT64:
                {
                    result = _iPLC.WriteInt64(addr, Convert.ToInt64(inputVal));
                    break;
                }

            case EValueType._FLOAT:
                {
                    result = _iPLC.WriteFloat(addr, (float)Convert.ToDouble(inputVal));
                    break;
                }

            case EValueType._DOUBLE:
                {
                    result = _iPLC.WriteDouble(addr, Convert.ToDouble(inputVal));
                    break;
                }

            case EValueType._STRING:
                {
                    result = _iPLC.WriteString(addr, inputVal);
                    break;
                }

            default:
                result = false;
                break;
        }

        return result;
    }

    public List<T> ToList<T>(T[] input)
    {
        return input.ToList();
    }

    /// <summary>
    /// 默认直接用数据库中的类型,如果是手动选择的,不要用
    /// </summary>
    /// <param name="valueTypeStr"></param>
    /// <param name="address"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public string GetValueByTypeString(string valueTypeStr, string address)
    {
        switch (valueTypeStr.ToUpper())
        {
            case "BOOL":
                return Convert.ToInt16(this.ReadBool(address)).ToString();
            case "INT_16":
            case "INT":
            case "SHORT":
            case "WORD":
                return this.ReadInt16(address).ToString();
            case "DWORD":
            case "DINT":
            case "UINT":
                return this.ReadInt32(address).ToString();
            case "TIME":
            case "REAL":
            case "FLOAT":
                return this.ReadFloat(address).ToString("0.00");
            case "LREAL":
            case "DOUBLE":
                return this.ReadDouble(address).ToString("0.00");
            default:
                throw new IndexOutOfRangeException($"该类型的PLC地址{valueTypeStr.ToUpper()}尚未定义转换类型!");
        }
    }

    public string GetBytesValueByTypeString(string valueTypeStr, byte[] values, int Lenth)
    {

        switch (valueTypeStr.ToUpper())
        {
            case "INT_16":
            case "INT":
            case "SHORT":
            case "WORD":
                values = values.Skip(Lenth * 2).Take(4).ToArray();
                return BitConverter.ToInt32(ByteArrayFormat(values), 0).ToString();
            case "DWORD":
            case "DINT":
            case "UINT":
                values = values.Skip(Lenth * 2).Take(4).ToArray();
                return BitConverter.ToUInt32(ByteArrayFormat(values), 0).ToString();
            case "TIME":
            case "REAL":
            case "FLOAT":
                //values = values.Skip(Lenth * 2).Take(4).ToArray();
                return BitConverter.ToSingle(ByteArrayFormat(values.Skip(Lenth * 2).Take(4).ToArray()), 0).ToString();
            case "LREAL":
            case "DOUBLE":
                //values = values.Skip(Lenth * 2).Take(4).ToArray();
                return BitConverter.ToDouble(ByteArrayFormat(values.Skip(Lenth * 2).Take(8).ToArray()), 0).ToString();
            default:
                throw new IndexOutOfRangeException($"该类型的PLC地址{valueTypeStr.ToUpper()}尚未定义转换类型!");
        }
    }

    private byte[] ByteArrayFormat(byte[] array)
    {
        for (int i = 0; 2 * i + 1 < array.Length; i++)
        {
            byte temp = array[2 * i];
            array[2 * i] = array[2 * i + 1];
            array[2 * i + 1] = temp;
        }
        return array;
    }

    public List<string> GetValueByTypeStringList(string typeStr, string address, ushort length)
    {
        switch (typeStr.ToUpper())
        {
            case "BOOL":
                return this.ReadBool(address, length)?.Select<bool, string>(bVal => bVal.ToString()).ToList();
            case "INT_16":
            case "INT":
            case "SINT":
            case "SHORT":
            case "WORD":
            case "BYTE":
                return this.ReadInt16(address, length)?.Select<short, string>(val => val.ToString()).ToList();
            case "USINT":
            case "UINT":
                return this.ReadUInt16(address, length)?.Select<ushort, string>(val => val.ToString()).ToList();
            case "DWORD":
            case "DINT":
                return this.ReadInt32(address, length)?.Select<int, string>(val => val.ToString()).ToList();
            case "UDINT":
                return this.ReadUInt32(address, length)?.Select<uint, string>(val => val.ToString()).ToList();
            case "LWORD":
            case "LINT":
                return this.ReadInt64(address, length)?.Select<long, string>(val => val.ToString()).ToList();
            case "ULINT":
                return this.ReadUInt64(address, length)?.Select<ulong, string>(val => val.ToString()).ToList();
            case "TIME":
            case "REAL":
            case "FLOAT":
                return this.ReadFloat(address, length)?.Select<float, string>(val => val.ToString()).ToList();
            case "LREAL":
            case "DOUBLE":
                return this.ReadDouble(address, length)?.Select<double, string>(val => val.ToString()).ToList();
            default:
                throw new IndexOutOfRangeException($"该类型的PLC地址{typeStr.ToUpper()}尚未定义转换类型!");
        }
    }

    /// <summary>
    /// 默认直接用数据库中的类型,如果是手动选择的,不要用
    /// </summary>
    /// <param name="typeStr"></param>
    /// <param name="address"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public bool SetValueByTypeString(string typeStr, string address, string value)
    {
        switch (typeStr.ToUpper())
        {
            case "BOOL":
                return this.WriteBool(address, Convert.ToBoolean(short.Parse(value)));
            case "INT_16":
            case "INT":
            case "SINT":
            case "SHORT":
            case "WORD":
            case "BYTE":
                return this.WriteInt16(address, short.Parse(value));
            case "USINT":
            case "UINT":
                return this.WriteUInt16(address, ushort.Parse(value));
            case "DWORD":
            case "DINT":
                return this.WriteInt32(address, int.Parse(value));
            case "UDINT":
                return this.WriteUInt32(address, uint.Parse(value));
            case "LWORD":
            case "LINT":
                return this.WriteInt64(address, long.Parse(value));
            case "ULINT":
                return this.WriteUInt64(address, ulong.Parse(value));
            case "TIME":
            case "REAL":
            case "FLOAT":
                return this.WriteFloat(address, float.Parse(value));
            case "LREAL":
            case "DOUBLE":
                return this.WriteDouble(address, double.Parse(value));
            default:
                throw new IndexOutOfRangeException("该类型的PLC地址尚未定义转换类型!");
        }
    }
}
 public class Modbus_PLC : Hmx_PLCBase, IPLCBase
 {
     #region 目前还没用上
     public UInt16 Site { get; set; } = 2;
     public UInt16 ConnTimeout { get; set; } = 300;

     #endregion
     /// <summary>
     ///  获取参数值
     /// </summary>
     /// <typeparam name="TParam">参数类型</typeparam>
     /// <param name="Params"></param>
     /// <param name="paramName">参数名</param>
     /// <returns>参数值</returns>
     public static TParam Get<TParam>(ConnectionParamDictionary Params, string paramName)
     {
         TParam result;

         try
         {
             if (typeof(TParam).IsEnum)
             {
                 result = (TParam)Enum.Parse(typeof(TParam), Params[paramName.ToLower()]);
             }
             else
             {
                 result = (TParam)Convert.ChangeType(Params[paramName.ToLower()], typeof(TParam));
             }
         }
         catch (Exception ex)
         {
             throw new ArgumentException($@"获取参数失败,异常:{ex},参数名:{paramName}");
         }

         return result;
     }
     public Modbus_PLC(string ip, ushort port, byte node = 1)
     {
         IP = ip;
         Port = port;
         Node = node;
     }
   
     /// <summary>
     /// 从机号
     /// </summary>
     private Byte Node { get; set; } = 1;

     public enum EHcOperate { Read, Write }
     public enum EHcCmd
     {
         ReadQ = 0x01,
         ReadI = 0x02,
         ReadM = 0x03,

         WriteQ = 0x05,
         WriteM = 0x06,

         WriteQs = 0x0F,
         WriteMs = 0x10,
     }

     public enum EHcAddrType { QX, IX, MX, MW, MD };

     public class HcAddrInfo
     {
         public EHcOperate opt { get; set; } = EHcOperate.Read;
         public EHcCmd cmd { get; set; } = EHcCmd.ReadQ;
         public EValueType valueType { get; set; } = EValueType._BOOL;
         public EHcAddrType addrType { get; set; } = EHcAddrType.QX;
         public string addrStr { get; set; } = "";
         public UInt16 addrValue { get; set; } = 0;
         public UInt16 count { get; set; } = 0;
         public UInt16 mwCount { get; set; } = 0;
         public UInt16 mwOffset { get; set; } = 0;

     }


     private List<byte> header = new List<byte>();





     //只处理M区
     public List<T> ParseReadRecv<T>(byte[] recvmsg, HcAddrInfo addrInfo, ref List<T> rst, EValueType valueType)
     {
         switch (valueType)
         {
             case EValueType._BOOL:
                 {
                     int recvSize = recvmsg.Count();
                     int dataLen = (addrInfo.count + addrInfo.mwOffset + 15) / 16 * 2;
                     List<byte> dataByte = new List<byte>();
                     List<bool> dataBool = new List<bool>();
                     if (recvSize == dataLen + 9)
                     {
                         //两个两个的转
                         for (int i = 0; i < dataLen; i += 2)
                         {
                             dataByte.AddRange(recvmsg.Skip(9 + i).Take(2).Reverse().ToArray());
                         }

                         BitArray ba = new BitArray(dataByte.ToArray());
                         foreach (var item in ba) { dataBool.Add((bool)item); }

                         List<bool> result = dataBool.Skip(addrInfo.mwOffset).Take(addrInfo.count).ToList();

                         for (int i = 0; i < result.Count; i++)
                         {
                             rst.Add((T)(Object)result[i]);
                         }
                     }
                 }
                 break;
             case EValueType._INT16:
                 {
                     int recvSize = recvmsg.Count();
                     int dataLen = addrInfo.mwCount * 2;

                     if (recvSize == dataLen + 9)
                     {
                         for (int i = recvSize - dataLen; i < recvSize; i += 2)
                         {
                             rst.Add((T)(Object)BitConverter.ToInt16(recvmsg.Skip(i).Take(2).Reverse().ToArray(), 0));
                         }
                     }
                 }
                 break;

             case EValueType._UINT16:
                 {
                     int recvSize = recvmsg.Count();
                     int dataLen = addrInfo.mwCount * 2;

                     if (recvSize == dataLen + 9)
                     {
                         for (int i = recvSize - dataLen; i < recvSize; i += 2)
                         {
                             rst.Add((T)(Object)BitConverter.ToUInt16(recvmsg.Skip(i).Take(2).Reverse().ToArray(), 0));
                         }
                     }
                 }
                 break;

             case EValueType._INT32:
                 {
                     int recvSize = recvmsg.Count();
                     int dataLen = addrInfo.mwCount * 2;
                     if (recvSize == dataLen + 9)
                     {
                         for (int i = recvSize - dataLen; i < recvSize; i += 4)
                         {
                             var bytes = recvmsg.Skip(i).Take(8).ToArray();
                             if (bytes.Length != 4)
                                 return rst;
                             bytes = FormatConversion(bytes);
                             rst.Add((T)(Object)BitConverter.ToInt32(bytes, 0));
                         }
                     }
                 }
                 break;
             case EValueType._INT64:
                 {
                     int recvSize = recvmsg.Count();
                     int dataLen = addrInfo.mwCount * 2;

                     if (recvSize == dataLen + 9)
                     {
                         for (int i = recvSize - dataLen; i < recvSize; i += 8)
                         {
                             var bytes = recvmsg.Skip(i).Take(8).ToArray();
                             if (bytes.Length != 8)
                                 return rst;
                             bytes = FormatConversion(bytes);
                             rst.Add((T)(Object)BitConverter.ToInt64(bytes, 0));
                         }
                     }
                 }
                 break;

             case EValueType._FLOAT:
                 {
                     int recvSize = recvmsg.Count();
                     int dataLen = addrInfo.mwCount * 2;

                     if (recvSize == dataLen + 9)
                     {
                         for (int i = recvSize - dataLen; i < recvSize; i += 4)
                         {
                             var bytes = recvmsg.Skip(i).Take(8).ToArray();
                             if (bytes.Length != 4)
                                 return rst;
                             bytes = FormatConversion(bytes);
                             rst.Add((T)(Object)BitConverter.ToSingle(bytes, 0));
                         }
                     }
                 }
                 break;

             case EValueType._DOUBLE:
                 {
                     int recvSize = recvmsg.Count();
                     int dataLen = addrInfo.mwCount * 2;

                     if (recvSize == dataLen + 9)
                     {
                         for (int i = recvSize - dataLen; i < recvSize; i += 8)
                         {
                             var bytes = recvmsg.Skip(i).Take(8).ToArray();
                             if (bytes.Length != 8)
                                 return rst;
                             bytes = FormatConversion(bytes);
                             rst.Add((T)(Object)BitConverter.ToDouble(bytes, 0));
                         }
                     }
                 }
                 break;
             case EValueType._STRING:
                 {
                     int recvSize = recvmsg.Count();
                     int dataLen = addrInfo.mwCount * 2;

                     //  if (recvSize == dataLen + 9)
                     if (recvSize > 9)
                     {
                         rst.Add((T)(Object)System.Text.Encoding.UTF8.GetString(recvmsg.Skip(9).ToArray()));
                     }
                 }
                 break;
             default:
                 break;
         }
         return rst;
     }



     public byte[] getReadSend(HcAddrInfo addrInfo)
     {
         Byte[] rst;
         List<byte> data = new List<byte>();
         data.Add(Node);                                                                   // 从机地址
         data.Add((byte)addrInfo.cmd);                                                     // 指令
         data.AddRange(BitConverter.GetBytes(addrInfo.addrValue).Reverse());               // 地址
         if (addrInfo.addrType == EHcAddrType.MX ||
             addrInfo.addrType == EHcAddrType.MW)
             data.AddRange(BitConverter.GetBytes((ushort)addrInfo.mwCount).Reverse());     // 数量          
         else
             data.AddRange(BitConverter.GetBytes(addrInfo.count).Reverse());               // 数量

         List<byte> send = new List<byte>();
         send.AddRange(new byte[] { 0x00, 0x00 });                                         // 事务标识符;
         send.AddRange(new byte[] { 0x00, 0x00 });                                         // 协议标识符;
         send.AddRange(BitConverter.GetBytes((ushort)data.Count()).Reverse());             // 长度;
         send.AddRange(data);
         rst = send.ToArray();
         return rst;
     }

     public HcAddrInfo ConvertToAddr(string addr, ushort count, EValueType valueType, EHcOperate opt, bool isMulti = true)
     {
         // [1] 地址信息赋值
         HcAddrInfo rst = new HcAddrInfo() { opt = opt, count = count, valueType = valueType, addrStr = addr };

         // [2] 分离前缀与地址
         String addrTypeStr = "";
         String addrValueStr = "";

         Regex r = new Regex("[A-Za-z]+");
         var m = r.Match(addr);
         if (m.Success)
             addrTypeStr = m.Groups[0].ToString();

         addrValueStr = addr.Remove(0, addrTypeStr.Length);

         // [3] 解析地址类型
         switch (addrTypeStr)
         {
             case "MX":
                 {
                     rst.cmd = EHcOperate.Read == opt ? EHcCmd.ReadM : EHcCmd.WriteM;

                     var num = addrValueStr.Split('.');
                     if (num.Count() == 1)
                         rst.mwOffset = Convert.ToInt32(num[0]) % 2 == 0 ? (ushort)0 : (ushort)8;
                     else if (num.Count() == 2)
                         rst.mwOffset = Convert.ToInt32(num[0]) % 2 == 0 ? Convert.ToUInt16(num[1]) : (ushort)(Convert.ToUInt16(num[1]) + 8);

                     rst.addrType = EHcAddrType.MX;
                     rst.addrValue = (ushort)((Convert.ToInt32(num[0]) / 2));
                     rst.mwCount = (ushort)((rst.count + rst.mwOffset + 15) / 16);
                 }
                 break;
             case "MB":
                 {
                     rst.cmd = EHcOperate.Read == opt ? EHcCmd.ReadM : EHcCmd.WriteM;

                     var num = addrValueStr.Split('.');
                     if (num.Count() == 1)
                         rst.mwOffset = Convert.ToInt32(num[0]) % 2 == 0 ? (ushort)0 : (ushort)8;
                     else if (num.Count() == 2)
                         rst.mwOffset = Convert.ToInt32(num[0]) % 2 == 0 ? Convert.ToUInt16(num[1]) : (ushort)(Convert.ToUInt16(num[1]) + 8);

                     rst.addrType = EHcAddrType.MX;
                     rst.addrValue = (ushort)((Convert.ToInt32(num[0]) / 2));
                     rst.mwCount = (ushort)((rst.count + rst.mwOffset + 15) / 16);
                 }
                 break;
             case "MW":
                 {
                     if (EHcOperate.Read == opt)
                         rst.cmd = EHcCmd.ReadM;
                     else
                         rst.cmd = isMulti ? EHcCmd.WriteMs : EHcCmd.WriteM;

                     switch (rst.valueType)
                     {
                         case EValueType._INT16: rst.mwCount = 1; break;
                         case EValueType._INT32: rst.mwCount = 2; break;
                         case EValueType._INT64: rst.mwCount = 4; break;
                         case EValueType._UINT16: rst.mwCount = 1; break;
                         case EValueType._UINT32: rst.mwCount = 2; break;
                         case EValueType._UINT64: rst.mwCount = 4; break;
                         case EValueType._FLOAT: rst.mwCount = 2; break;
                         case EValueType._DOUBLE: rst.mwCount = 4; break;
                         case EValueType._STRING: rst.mwCount = 1; break;
                     }

                     rst.mwCount = (ushort)(rst.mwCount * count);
                     rst.addrType = EHcAddrType.MW;
                     rst.addrValue = Convert.ToUInt16(addrValueStr);
                 }
                 break;

             default:
                 break;
         }
         return rst;
     }

     private bool SocketSend(byte[] array, ref int recvlen, ref byte[] recvmsg)
     {
         mutex.WaitOne();
         try
         {
             if (array.Length != SocketClient.Send(array))
                 return false;

             recvlen = SocketClient.Receive(recvmsg);
         }
         catch (Exception ex)
         {
             Console.WriteLine(ex.ToString());

         }

         mutex.ReleaseMutex();
         return true;

     }



     #region  写方法
     public bool WriteInt32(String addr, int value)
     {
         return WriteValue(addr, value, EValueType._INT32);
     }

     public bool WriteInt16(String addr, short value)
     {
         return WriteValue(addr, value, EValueType._INT16);
     }

     public bool WriteBool(String addr, bool value)
     {
         return WriteValue(addr, value, EValueType._BOOL);
     }

     public bool WriteFloat(String addr, float value)
     {
         return WriteValue(addr, value, EValueType._FLOAT);
     }

     public bool WriteDouble(String addr, Double value)
     {
         return WriteValue(addr, value, EValueType._DOUBLE);
     }

     public bool WriteString(String addr, string value)
     {
         return WriteValue(addr, value, EValueType._STRING);
     }

     public bool WriteValue(String addr, object value, EValueType valueType, bool IsMult = true)
     {
         bool rst = false;

         if (!IsConnect)
             return rst;

         var addrInfo = ConvertToAddr(addr, 1, valueType, EHcOperate.Write, IsMult);
         var sendInfo = GetWriteSend(addrInfo, value, valueType);

         byte[] recvmsg = new byte[65535];
         int len = 0;
         SocketSend(sendInfo, ref len, ref recvmsg);
         rst = parseWriteRecv(recvmsg);
         return rst;
     }


     public Byte[] GetWriteSend(HcAddrInfo addrInfo, object value, EValueType valueType)
     {
         Byte[] rst;
         List<byte> data = new List<byte>();

         data.Add(Node);         // 从机地址
         data.Add((Byte)addrInfo.cmd); // 指令
         data.AddRange(BitConverter.GetBytes(addrInfo.addrValue).Reverse());       // 地址高位

         switch (valueType)
         {
             case EValueType._BOOL:
                 {
                     List<short> temp = new List<short>();
                     var ret = ReadValue(addrInfo.addrStr, 1, EValueType._INT16, ref temp);
                     var bits = BitConverter.GetBytes(ret[0]);
                     BitArray bitSet = new BitArray(bits);
                     bitSet[addrInfo.mwOffset] = (bool)value;

                     bitSet.CopyTo(bits, 0); //复制 8 个bit
                     data.AddRange(bits.Reverse());
                 }
                 break;
             case EValueType._INT16:
                 {
                     //data.AddRange(BitConverter.GetBytes(Convert.ToInt16(value)).Reverse());
                     data.AddRange(BitConverter.GetBytes((ushort)addrInfo.mwCount).Reverse());       // 数量高位
                     data.Add((byte)(addrInfo.mwCount * 2));              // 字节数
                     data.AddRange(BitConverter.GetBytes(Convert.ToInt16(value)).Reverse());
                 }
                 break;
             case EValueType._INT32:
                 {
                     data.AddRange(BitConverter.GetBytes((ushort)addrInfo.mwCount).Reverse());       // 数量高位
                     data.Add((byte)(addrInfo.mwCount * 2));              // 字节数
                     var temp = BitConverter.GetBytes(Convert.ToInt32(value));
                     temp = FormatConversion(temp);
                     data.AddRange(temp);

                 }
                 break;
             case EValueType._INT64:
                 {
                     data.AddRange(BitConverter.GetBytes((ushort)addrInfo.mwCount).Reverse());       // 数量高位
                     data.Add((byte)(addrInfo.mwCount * 2));              // 字节数
                     var temp = BitConverter.GetBytes(Convert.ToInt64(value));
                     temp = FormatConversion(temp);
                     data.AddRange(temp);
                 }
                 break;
             case EValueType._FLOAT:
                 {
                     data.AddRange(BitConverter.GetBytes((ushort)addrInfo.mwCount).Reverse());       // 数量高位
                     data.Add((byte)(addrInfo.mwCount * 2));              // 字节数
                                                                          //data.AddRange(BitConverter.GetBytes(Convert.ToSingle(value)).Reverse());
                     var temp = BitConverter.GetBytes(Convert.ToSingle(value));
                     temp = FormatConversion(temp);
                     data.AddRange(temp);
                 }
                 break;
             case EValueType._DOUBLE:
                 {
                     data.AddRange(BitConverter.GetBytes((ushort)addrInfo.mwCount).Reverse());       // 数量高位
                     data.Add((byte)(addrInfo.mwCount * 2));              // 字节数
                     var temp = BitConverter.GetBytes(Convert.ToDouble(value));
                     temp = FormatConversion(temp);
                     data.AddRange(temp);
                 }
                 break;

             case EValueType._STRING:
                 {
                     var valueTemp = System.Text.Encoding.UTF8.GetBytes(value.ToString()).ToList();
                     if (valueTemp.Count() % 2 != 0)
                         valueTemp.Add((byte)0);

                     data.AddRange(BitConverter.GetBytes((ushort)(valueTemp.Count() / 2)).Reverse());       // 数量高位
                                                                                                            //data.Add((byte)(valueTemp.Count()/2 == 0? valueTemp.Count() : valueTemp.Count() + 1));   // 字节数
                     data.Add((byte)(valueTemp.Count()));   // 字节数
                     data.AddRange(valueTemp);
                 }
                 break;
             default:
                 break;
         }

         byte[] placeholder = new byte[] { 0x00, 0x00 };
         ushort dataLen = (ushort)data.Count();
         List<byte> send = new List<byte>();
         send.AddRange(placeholder);                      // 事务标识符;
         send.AddRange(placeholder);                      // 协议标识符;
         send.AddRange(BitConverter.GetBytes(dataLen).Reverse());       // 长度;
         send.AddRange(data);

         rst = send.ToArray();

         return rst;
     }

     public bool parseWriteRecv(byte[] recv)
     {
         bool rst = true;

         int errTypeIndex = 7;
         int errCodeIndex = 8;

         if (recv.Count() == 9)
         {
             if (recv[errTypeIndex] >= 0x80)
             {
                 var type = recv[errTypeIndex] - 0x80;
                 var code = BitConverter.ToInt32(recv, errCodeIndex);
                 rst = false;
             }
         }
         return rst;
     }
     #endregion

     #region 读方法
     public List<bool> ReadBools(string addr, ushort count)
     {
         List<bool> rst = new List<bool>();
         var ret = ReadValue(addr, count, EValueType._BOOL, ref rst);
         return ret;
     }

     public bool ReadBool(string addr)
     {
         List<bool> rst = new List<bool>();
         var ret = ReadValue(addr, 1, EValueType._BOOL, ref rst);
         return rst.Count() > 0 ? ret[0] : false;
     }

     public List<short> ReadInt16s(string addr, ushort len)
     {
         List<short> rst = new List<short>();
         var ret = ReadValue(addr, len, EValueType._INT16, ref rst);
         return rst;
     }

     public short ReadInt16(string addr)
     {
         List<short> rst = new List<short>();
         var ret = ReadValue(addr, 1, EValueType._INT16, ref rst);
         return rst.Count() > 0 ? ret[0] : (short)0;
     }

     public List<int> ReadInts(string addr, ushort len)
     {
         List<int> rst = new List<int>();
         var ret = ReadValue(addr, len, EValueType._INT32, ref rst);
         return rst;
     }


     public int ReadInt(string addr)
     {
         List<int> rst = new List<int>();
         var ret = ReadValue(addr, 1, EValueType._INT32, ref rst);
         return rst.Count() > 0 ? ret[0] : 0;
     }

     public List<long> ReadInt64s(string addr, ushort len)
     {
         List<long> rst = new List<long>();
         var ret = ReadValue(addr, len, EValueType._INT64, ref rst);
         return rst;
     }

     public long ReadInt64(string addr)
     {
         List<long> rst = new List<long>();
         var ret = ReadValue(addr, 1, EValueType._INT64, ref rst);
         return rst.Count() > 0 ? ret[0] : (long)0;
     }

     public List<float> ReadFloats(string addr, ushort len)
     {
         List<float> rst = new List<float>();
         var ret = ReadValue(addr, len, EValueType._FLOAT, ref rst);
         return rst;
     }
     public float ReadFloat(string addr)
     {
         List<float> rst = new List<float>();
         var ret = ReadValue(addr, 1, EValueType._FLOAT, ref rst);
         return rst.Count() > 0 ? ret[0] : (float)0;
     }

     public List<Double> ReadDoubles(string addr, ushort len)
     {
         List<Double> rst = new List<Double>();
         var ret = ReadValue(addr, len, EValueType._DOUBLE, ref rst);
         return rst;
     }
     public Double ReadDouble(string addr)
     {
         List<Double> rst = new List<Double>();
         var ret = ReadValue(addr, 1, EValueType._DOUBLE, ref rst);
         return rst.Count() > 0 ? ret[0] : (Double)0;
     }

     public string ReadString(string addr, ushort len)
     {
         List<string> rst = new List<string>();
         var ret = ReadValue(addr, len, EValueType._STRING, ref rst);
         return rst.Count() > 0 ? ret[0] : "";
     }

     public List<byte> ReadAllByte(string addr, UInt16 count = 65535)
     {
         List<byte> rst = new List<byte>();
         var ret = ReadValue(addr, count, EValueType._STRING, ref rst);
         return rst;
     }
     public List<T> ReadValue<T>(string addr, ushort count, EValueType valueType, ref List<T> rst)
     {
         if (!IsConnect)
             return rst;

         if (count <= 0)
             return rst;

         var addrInfo = ConvertToAddr(addr, count, valueType, EHcOperate.Read, false);
         var sendInfo = getReadSend(addrInfo);

         Console.WriteLine(BitConverter.ToString(sendInfo));

         int len = 0;
         byte[] recvmsg = new byte[1024];
         SocketSend(sendInfo, ref len, ref recvmsg);


         ParseReadRecv(recvmsg.Take(len).ToArray(), addrInfo, ref rst, valueType);

         return rst;
     }


     #endregion
     //public List<byte> ReadAllByte(string addr, ushort count = ushort.MaxValue)
     //{
     //    throw new NotImplementedException();
     //}

     public ushort ReadUInt16(string addr)
     {
         throw new NotImplementedException();
     }

     public List<ushort> ReadUInt16s(string addr, ushort count)
     {
         List<UInt16> rst = new List<UInt16>();
         var ret = ReadValue(addr, count, EValueType._UINT16, ref rst);
         return rst.Count() > 0 ? ret : null;
     }

     public string ReadString(string addr, ushort count, bool stringFormate = true)
     {
         List<string> rst = new List<string>();
         var ret = ReadValue(addr, count, EValueType._STRING, ref rst);
         return rst.Count() > 0 ? ret[0] : "ERROR";
     }

     public int ReadInt32(string addr)
     {
         List<int> rst = new List<int>();
         var ret = ReadValue(addr, 1, EValueType._INT32, ref rst);
         return rst.Count() > 0 ? ret[0] : 0;
     }

     public List<int> ReadInt32s(string addr, ushort count)
     {
         List<int> rst = new List<int>();
         var ret = ReadValue(addr, count, EValueType._INT32, ref rst);
         return rst.Count() == count ? rst : new List<int>();
     }

     public uint ReadUInt32(string addr)
     {
         List<uint> rst = new List<uint>();
         var ret = ReadValue(addr, 1, EValueType._UINT32, ref rst);
         return rst.Count() > 0 ? ret[0] : 0;
     }

     public List<uint> ReadUInt32s(string addr, ushort count)
     {
         List<uint> rst = new List<uint>();
         var ret = ReadValue(addr, count, EValueType._UINT32, ref rst);
         return rst.Count() == count ? rst : new List<uint>();
     }

     public ulong ReadUInt64(string addr)
     {
         List<UInt64> rst = new List<UInt64>();
         var ret = ReadValue(addr, 1, EValueType._UINT64, ref rst);
         return rst.Count() > 0 ? ret[0] : 0;
     }

     public List<ulong> ReadUInt64s(string addr, ushort count)
     {
         List<UInt64> rst = new List<UInt64>();
         var ret = ReadValue(addr, count, EValueType._UINT64, ref rst);
         return rst.Count() == count ? rst : new List<UInt64>();
     }

     public bool WriteBools(string addr, List<bool> value)
     {
         throw new NotImplementedException();
     }

     public bool WriteInt16s(string addr, List<short> value)
     {
         throw new NotImplementedException();
     }

     public bool WriteUInt16(string addr, ushort value)
     {
         throw new NotImplementedException();
     }

     public bool WriteUInt16s(string addr, List<ushort> value)
     {
         throw new NotImplementedException();
     }

     public bool WriteInt32s(string addr, List<int> value)
     {
         throw new NotImplementedException();
     }

     public bool WriteUInt32(string addr, uint value)
     {
         return true;
         throw new NotImplementedException();
     }

     public bool WriteUInt32s(string addr, List<uint> value)
     {
         throw new NotImplementedException();
     }

     public bool WriteInt64(string addr, long value)
     {
         throw new NotImplementedException();
     }

     public bool WriteInt64s(string addr, List<long> value)
     {
         throw new NotImplementedException();
     }

     public bool WriteUInt64(string addr, ulong value)
     {
         throw new NotImplementedException();
     }

     public bool WriteUInt64s(string addr, List<ulong> value)
     {
         throw new NotImplementedException();
     }

     public bool WriteDoubles(string addr, List<double> value)
     {
         throw new NotImplementedException();
     }

     public bool WriteFloats(string addr, List<float> value)
     {
         throw new NotImplementedException();
     }
     /// <summary>
     /// 写入PLC的值
     /// </summary>
     public string WriteValues;
     /// <summary>
     /// 写地址
     /// </summary>
     public string WriteAddress;
     /// <summary>
     /// 读地址
     /// </summary>
     public string ReadAddress;
     /// <summary>
     /// 读取长度(非字符串)
     /// </summary>
     public string Count;
     /// <summary>
     /// 读取字符长度
     /// </summary>
     public string NumberLength;
     /// <summary>
     /// 读取记录
     /// </summary>
     public string ReadLog;

 }

Job数采实例

表格存储 安装NuGet组件:EPPlus4.5

public class ExcelHelper
{
    public static string GetExcelFilePath(string filename)
    {
        // 获取当前日期并创建文件夹路径
        var directory = Path.Combine("D:", "HYMSON", DateTime.Now.ToString("yyyy-MM-dd"));

        // 创建目录(如果目录不存在)
        Directory.CreateDirectory(directory);

        // 返回文件的完整路径(文件名为当前日期)
        return Path.Combine(directory, $"{filename+"_"+ DateTime.Now.ToString("yyyy-MM-dd")}.xlsx");
    }
  

    public static void CreateAExcelFile(string filePath)
    {
        // 创建 Excel 文件并添加表头
        using (var package = new ExcelPackage(new FileInfo(filePath)))
        {
            var worksheet = package.Workbook.Worksheets.Add("Data");
            worksheet.Cells[1, 1].Value = "时间";
            worksheet.Cells[1, 2].Value = "长";
            worksheet.Cells[1, 3].Value = "隙";
            worksheet.Cells[1, 4].Value = "条码";          

            package.Save();
        }
    }
    public static void CreateBExcelFile(string filePath)
    {
        // 创建 Excel 文件并添加表头
        using (var package = new ExcelPackage(new FileInfo(filePath)))
        {
            var worksheet = package.Workbook.Worksheets.Add("Data");
            worksheet.Cells[1, 1].Value = "时间";
            worksheet.Cells[1, 2].Value = "实时值";
            worksheet.Cells[1, 3].Value = "实时值";
            worksheet.Cells[1, 4].Value = "条码";

            package.Save();
        }
    }

    public static void AppendDataToExcel(string filePath, DateTime time, float param1, float param2, string productCode)
    {
        using (var package = new ExcelPackage(new FileInfo(filePath)))
        {
            var worksheet = package.Workbook.Worksheets[0];
            var row = worksheet.Dimension.Rows + 1; // 获取下一行的行号
            worksheet.Cells[row, 1].Value = time.ToString();
            worksheet.Cells[row, 2].Value = param1.ToString("0.00");
            worksheet.Cells[row, 3].Value = param2.ToString("0.00");
            worksheet.Cells[row, 4].Value = productCode;
            package.Save();
        }
    }
}

使用:

 IPLC.Instance._iPLC = new Modbus_PLC("127.0.0.1",(ushort)502,1);
 IPLC.Instance.Connect();
[BackgroundJobDefine(cron: "*/1 * * * * ? *", "每3秒都执行")]
public class Interval_Job : PFBackgroundJob
{
    private readonly string _excelAFilePath;
    private readonly string _excelBFilePath;
    private readonly IA_ProductOutputService _a_productOutputService;
    private readonly IB_ProductOutputService _b_productOutputService;
    public Interval_Job(IA_ProductOutputService a_productOutputService, IB_ProductOutputService b_productOutputService)
    {
        _a_productOutputService = a_productOutputService;
        _b_productOutputService = b_productOutputService;
        _excelAFilePath = ExcelHelper.GetExcelFilePath("测长");
        if (!File.Exists(_excelAFilePath))
        {
            ExcelHelper.CreateAExcelFile(_excelAFilePath);
        }
        _excelBFilePath = ExcelHelper.GetExcelFilePath("对位");
        if (!File.Exists(_excelBFilePath))
        {
            ExcelHelper.CreateAExcelFile(_excelBFilePath);
        }
        CleanOldDirectories();
    }

    protected override async Task HandleAsync()
    {
        
        //写入 PLC 数据
           /* IPLC.Instance.WriteFloat("MW6000", 12.6f);
            IPLC.Instance.WriteFloat("MW6100", 12.7f);
            IPLC.Instance.WriteFloat("MW6204", 12.8f);
            IPLC.Instance.WriteFloat("MW6304", 12.9f);
            IPLC.Instance.WriteBool("MX3000.4", true);
            IPLC.Instance.WriteBool("MX3000.5", true);*/

            var flagA = IPLC.Instance.ReadBool("MX3000.4");
            var flagB = IPLC.Instance.ReadBool("MX3000.5");

            float paintLong = 0, interval = 0, tail = 0, head = 0;

            // 根据 flagA 和 flagB 判断是否需要读取其他数据
            if (flagA)
            {
                paintLong = IPLC.Instance.ReadFloat("MW6000");
                interval = IPLC.Instance.ReadFloat("MW6100");
                IPLC.Instance.WriteBool("MX3000.4", false);
                var pro = await GetProductCode();
                ExcelHelper.AppendDataToExcel(_excelAFilePath, DateTime.Now, paintLong, interval, pro);
            }

            if (flagB)
            {
                tail = IPLC.Instance.ReadFloat("MW6204");
                head = IPLC.Instance.ReadFloat("MW6304");
                IPLC.Instance.WriteBool("MX3000.4", false);
                var pro = await GetProductCode();
                ExcelHelper.AppendDataToExcel(_excelBFilePath, DateTime.Now, tail,  head, pro );
            }
          
        
    }

    public async Task<string> GetProductCode()
    {
        //是否生产
        bool AhasPOut = await this._a_productOutputService.IsProductionInAsync();
        bool BhasPOut = await this._b_productOutputService.IsProductionInAsync();
        var pro = string.Empty;
        if ((AhasPOut || BhasPOut))
        {           
            if (AhasPOut)
            {
                pro = (await _a_productOutputService.GetProductionInAsync()).ProductCode;
            }
            if (BhasPOut)
            {
                pro = (await _b_productOutputService.GetProductionInAsync()).ProductCode;
            }
        }
        return pro;
    }

    private void CleanOldDirectories()
    {
        var baseDirectory = Path.Combine("D:", "存放文件夹名称");
        var directoryInfo = new DirectoryInfo(baseDirectory);

        // 获取当前日期
        DateTime sixMonthsAgo = DateTime.Now.AddMonths(-6);

        // 遍历所有的子目录
        foreach (var directory in directoryInfo.GetDirectories())
        {
            // 判断文件夹的创建时间
            if (directory.CreationTime < sixMonthsAgo)
            {
                try
                {
                    directory.Delete(true); // true 表示递归删除
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Failed to delete directory {directory.Name}: {ex.Message}");
                }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值