Example #1
0
        private bool RequestData(IO_DEVICE device, RealData realData, out string error, ModbusFragmentStore fragmentstore)
        {
            error = "";
            try
            {
                if (udpClient != null)
                {
                    //分段读取数据,如果是读取整个寄存器的话,一次只能最多读取123个,
                    //如果是读取线圈的话最大只能读取1999个,因此要分段进行数据的读取
                    List <byte> allbytes = new List <byte>();
                    try
                    {
                        for (int i = 0; i < fragmentstore.Fragments.Count; i++)
                        {
                            ModbusFragment fragment = fragmentstore.Fragments[i];
                            switch (fragment.Code)
                            {
                            case "01":    // 01和05是一个码 可写可读
                            {
                                //返回的线圈状态,由于线圈是按位操作,转换也是按位转换
                                Task <bool[]> result = master.ReadCoilsAsync(byte.Parse(device.IO_DEVICE_ADDRESS), fragment.StartRegister, fragment.RegisterNum);

                                byte[] bytes = ModbusConvert.BoolToByte(result.Result);
                                fragment.StartIndex = allbytes.Count;
                                fragment.Length     = bytes.Length;
                                allbytes.AddRange(bytes);
                            }
                            break;

                            case "02":    //只读属性
                            {
                                //返回的线圈状态
                                Task <bool[]> result = master.ReadInputsAsync(byte.Parse(device.IO_DEVICE_ADDRESS), fragment.StartRegister, fragment.RegisterNum);
                                byte[]        bytes  = ModbusConvert.BoolToByte(result.Result);
                                fragment.StartIndex = allbytes.Count;
                                fragment.Length     = bytes.Length;
                                allbytes.AddRange(bytes);
                            }
                            break;

                            case "03":    //HR保持寄存器,可写可读
                            {
                                //返回的数据全部是ushort 需要将ushort 转换为byte在进行传递
                                Task <ushort[]> result = master.ReadHoldingRegistersAsync(byte.Parse(device.IO_DEVICE_ADDRESS), fragment.StartRegister, fragment.RegisterNum);
                                byte[]          bytes  = ModbusConvert.Ushorts2Bytes(result.Result);
                                fragment.StartIndex = allbytes.Count;
                                fragment.Length     = bytes.Length;
                                allbytes.AddRange(bytes);
                            }
                            break;

                            case "04":    //只读属性
                            {
                                //返回的数据全部是ushort 需要将ushort 转换为byte在进行传递
                                Task <ushort[]> result = master.ReadInputRegistersAsync(byte.Parse(device.IO_DEVICE_ADDRESS), fragment.StartRegister, fragment.RegisterNum);
                                byte[]          bytes  = ModbusConvert.Ushorts2Bytes(result.Result);
                                fragment.StartIndex = allbytes.Count;
                                fragment.Length     = bytes.Length;
                                allbytes.AddRange(bytes);
                            }
                            break;
                            }
                        }
                    }
                    catch
                    {
                        //读取异常处理
                        this.DeviceStatus(this.IOServer, this.IOCommunication, device, null, "0");//tag为1表示上线,如果为0表示下线
                    }
                    //将数据返回到采集客户端
                    if (allbytes.Count > 0)
                    {
                        device.IO_DEVICE_STATUS = 1;
                        ReceiveData(this.IOServer, this.IOCommunication, device, allbytes.ToArray(), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), fragmentstore);
                        //设置设备状态
                        this.DeviceStatus(this.IOServer, this.IOCommunication, device, null, "1");//tag为1表示上线,如果为0表示下线
                    }
                    else
                    {
                        device.IO_DEVICE_STATUS = 0;
                        //设置设备状态
                        this.DeviceStatus(this.IOServer, this.IOCommunication, device, null, "0");//tag为1表示上线,如果为0表示下线
                    }
                }
                return(true);
            }
            catch
            {
                return(false);
            }
        }
Example #2
0
        /// <summary>
        /// 解析数据
        /// </summary>
        /// <param name="server"></param>
        /// <param name="Communication"></param>
        /// <param name="device"></param>
        /// <param name="para"></param>
        /// <param name="datas"></param>
        /// <param name="datatime"></param>
        /// <param name="sender"></param>
        /// <returns></returns>
        protected override IOData Analysis(IO_SERVER server, IO_COMMUNICATION Communication, IO_DEVICE device, IO_PARA para, byte[] datas, DateTime datatime, object sender)
        {
            if (datas.Length > 0 && sender != null && para != null)
            {
                ParaPack            paraPack    = new ParaPack(para.IO_PARASTRING);
                ModbusFragmentStore modbusStore = (ModbusFragmentStore)sender;
                IOData data = new IOData();
                data.CommunicationID = Communication.IO_COMM_ID;
                data.ID       = device.IO_DEVICE_ADDRESS;
                data.ParaName = para.IO_NAME;
                data.ServerID = server.SERVER_ID;
                data.Date     = DateTime.Now;
                Modbus_Type dataType = (Modbus_Type)Enum.Parse(typeof(Modbus_Type), paraPack.GetValue("数据类型"));
                switch (dataType)
                {
                case Modbus_Type.单精度浮点数32位:
                    data.DataType = typeof(float);
                    break;

                case Modbus_Type.双精度浮点数64位:
                    data.DataType = typeof(double);
                    break;

                case Modbus_Type.字符型:
                    data.DataType = typeof(string);
                    break;

                case Modbus_Type.无符号整数16位:
                    data.DataType = typeof(UInt16);
                    break;

                case Modbus_Type.无符号整数32位:
                    data.DataType = typeof(UInt32);
                    break;

                case Modbus_Type.无符号整数8位:
                    data.DataType = typeof(byte);
                    break;

                case Modbus_Type.符号整数16位:
                    data.DataType = typeof(Int16);
                    break;

                case Modbus_Type.符号整数8位:
                    data.DataType = typeof(sbyte);
                    break;

                case Modbus_Type.符号整数32位:
                    data.DataType = typeof(int);
                    break;
                }
                data.datas      = datas;
                data.ParaString = para.IO_PARASTRING;
                //获取数据值高八位,低八位
                int            startaddr = int.Parse(paraPack.GetValue("偏置"));
                int            charsize  = int.Parse(paraPack.GetValue("字节长度"));
                string         code      = paraPack.GetValue("内存区");
                bool           bitSave   = paraPack.GetValue("按位存取") == "1" ? true : false;
                bool           ishigh    = paraPack.GetValue("存储位置") == "高八位" ? true : false;
                ModbusFragment fragment  = modbusStore.Fragments.Find(x => x.Code == code && startaddr >= x.StartRegister && startaddr <= x.StartRegister + x.RegisterNum);
                if (fragment != null)
                {
                    switch (code)
                    {
                    case "01":    //线圈
                    {
                        byte[] vdatas = new byte[fragment.Length];
                        Array.Copy(datas, fragment.StartIndex, vdatas, 0, fragment.Length);
                        data.ParaValue = vdatas[startaddr].ToString();
                    }
                    break;

                    case "02":    //线圈只读
                    {
                        byte[] vdatas = new byte[fragment.Length];
                        Array.Copy(datas, fragment.StartIndex, vdatas, 0, fragment.Length);
                        data.ParaValue = vdatas[startaddr].ToString();
                    }
                    break;

                    case "03":    //寄存器可读可写
                    {
                        //注意是否按位读取,
                        byte[] vdatas = new byte[fragment.Length];
                        Array.Copy(datas, fragment.StartIndex, vdatas, 0, fragment.Length);
                        ushort[] vals = ModbusConvert.Bytes2Ushorts(vdatas);        //将字节数组转为ushort
                        switch (dataType)
                        {
                        case Modbus_Type.单精度浮点数32位:
                        {
                            data.ParaValue = ModbusConvert.GetReal(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.双精度浮点数64位:
                        {
                            data.ParaValue = ModbusConvert.GetDouble(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.字符型:
                        {
                            data.ParaValue = ModbusConvert.GetString(vals, 0, charsize).ToString();
                        }
                        break;

                        case Modbus_Type.无符号整数16位:
                        {
                            data.ParaValue = ModbusConvert.GetUShort(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.无符号整数32位:
                        {
                            data.ParaValue = ModbusConvert.GetUInt(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.无符号整数8位:
                        {
                            data.ParaValue = ModbusConvert.GetSByte(vals, 0, ishigh).ToString();
                        }
                        break;

                        case Modbus_Type.符号整数16位:
                        {
                            data.ParaValue = ModbusConvert.GetShort(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.符号整数8位:
                        {
                            data.ParaValue = ModbusConvert.GetByte(vals, 0, ishigh).ToString();
                        }
                        break;

                        case Modbus_Type.符号整数32位:
                        {
                            data.ParaValue = ModbusConvert.GetInt(vals, 0).ToString();
                        }
                        break;
                        }
                    }
                    break;

                    case "04":    //寄存器只读
                    {
                        //注意是否按位读取,
                        byte[] vdatas = new byte[fragment.Length];
                        Array.Copy(datas, fragment.StartIndex, vdatas, 0, fragment.Length);
                        ushort[] vals = ModbusConvert.Bytes2Ushorts(vdatas);        //将字节数组转为ushort
                        switch (dataType)
                        {
                        case Modbus_Type.单精度浮点数32位:
                        {
                            data.ParaValue = ModbusConvert.GetReal(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.双精度浮点数64位:
                        {
                            data.ParaValue = ModbusConvert.GetDouble(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.字符型:
                        {
                            data.ParaValue = ModbusConvert.GetString(vals, 0, charsize).ToString();
                        }
                        break;

                        case Modbus_Type.无符号整数16位:
                        {
                            data.ParaValue = ModbusConvert.GetUShort(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.无符号整数32位:
                        {
                            data.ParaValue = ModbusConvert.GetUInt(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.无符号整数8位:
                        {
                            data.ParaValue = ModbusConvert.GetSByte(vals, 0, ishigh).ToString();
                        }
                        break;

                        case Modbus_Type.符号整数16位:
                        {
                            data.ParaValue = ModbusConvert.GetShort(vals, 0).ToString();
                        }
                        break;

                        case Modbus_Type.符号整数8位:
                        {
                            data.ParaValue = ModbusConvert.GetByte(vals, 0, ishigh).ToString();
                        }
                        break;

                        case Modbus_Type.符号整数32位:
                        {
                            data.ParaValue = ModbusConvert.GetInt(vals, 0).ToString();
                        }
                        break;
                        }
                    }
                    break;
                    }
                }
            }
            return(null);
        }