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); } }
private bool ResponseData(IO_SERVER server, IO_COMMUNICATION comm, IO_DEVICE device, IO_PARA para, string value) { if (para == null) { return(false); } if (para.IO_POINTTYPE == "计算值" || para.IO_POINTTYPE == "关系数据库值") { return(false); } //设备地址不能为空 if (device.IO_DEVICE_ADDRESS == "") { return(false); } try { //通过设备驱动进行数据解析,并生成下置的数据bytes if (device.DeviceDrive != null) { ScadaDeviceKernel Driver = (ScadaDeviceKernel)device.DeviceDrive; //获取参数中的 if (udpClient != null && master != null) { ParaPack paraPack = new ParaPack(para.IO_PARASTRING); if (paraPack.Count > 0) { ushort offset = ushort.Parse(paraPack.GetValue("偏置")); switch (paraPack.GetValue("内存区")) { case "01": { if (ushort.Parse(value) > 0) { master.WriteSingleCoil(byte.Parse(device.IO_DEVICE_ADDRESS), offset, true); } else { master.WriteSingleCoil(byte.Parse(device.IO_DEVICE_ADDRESS), offset, false); } } break; case "02": //此类型只能查询,不能写入 { } break; case "03": { Modbus_Type datatype = (Modbus_Type)Enum.Parse(typeof(Modbus_Type), paraPack.GetValue("数据类型")); bool ishigh = paraPack.GetValue("存储位置") == "高八位" ? true : false; int charsize = int.Parse(paraPack.GetValue("字节长度")); bool isposition = paraPack.GetValue("按位存取") == "1" ? true : false; int dataposition = int.Parse(paraPack.GetValue("数据位")); switch (datatype) { case Modbus_Type.单精度浮点数32位: { ushort[] buff = new ushort[2]; float WriteValue = float.Parse(value); ModbusConvert.SetReal(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(device.IO_DEVICE_ADDRESS), offset, buff); } break; case Modbus_Type.双精度浮点数64位: { ushort[] buff = new ushort[4]; double WriteValue = double.Parse(value); ModbusConvert.SetDouble(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(device.IO_DEVICE_ADDRESS), offset, buff); } break; case Modbus_Type.字符型: { ushort[] buff = new ushort[charsize]; string WriteValue = value; if (value.Length > charsize) { WriteValue = value.Substring(0, charsize); } if (value.Length < charsize) { WriteValue = value.PadRight(charsize, ' '); } ModbusConvert.SetString(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(device.IO_DEVICE_ADDRESS), offset, buff); } break; case Modbus_Type.无符号整数8位: { ushort[] buff = new ushort[1]; byte WriteValue = byte.Parse(value); ModbusConvert.SetByte(buff, 0, WriteValue, ishigh); master.WriteSingleRegister(byte.Parse(device.IO_DEVICE_ADDRESS), offset, buff[0]); } break; case Modbus_Type.符号整数8位: { ushort[] buff = new ushort[1]; sbyte WriteValue = sbyte.Parse(value); ModbusConvert.SetSByte(buff, 0, WriteValue, ishigh); master.WriteSingleRegister(byte.Parse(device.IO_DEVICE_ADDRESS), offset, buff[0]); } break; case Modbus_Type.无符号整数16位: { if (isposition) { //获取当前寄存器的值 ushort[] datas = master.ReadHoldingRegisters(byte.Parse(device.IO_DEVICE_ADDRESS), offset, 1); ushort dataValue = ModbusConvert.GetUShort(datas, 0); if (short.Parse(value) > 0) { dataValue = Convert.ToUInt16(dataValue >> dataposition & 1); } else { dataValue = Convert.ToUInt16(dataValue >> dataposition & 0); } //新发送的值 ushort[] datas2 = new ushort[1]; ModbusConvert.SetUShort(datas2, 0, dataValue); master.WriteSingleRegister(byte.Parse(device.IO_DEVICE_ADDRESS), offset, datas2[0]); } else { ushort WriteValue = ushort.Parse(value); ushort[] buff = new ushort[1]; ModbusConvert.SetUShort(buff, 0, WriteValue); master.WriteSingleRegister(byte.Parse(device.IO_DEVICE_ADDRESS), offset, buff[0]); } } break; case Modbus_Type.符号整数16位: { if (isposition) { //获取当前寄存器的值 ushort[] datas = master.ReadHoldingRegisters(byte.Parse(device.IO_DEVICE_ADDRESS), offset, 1); short dataValue = ModbusConvert.GetShort(datas, 0); if (short.Parse(value) > 0) { dataValue = Convert.ToInt16(dataValue >> dataposition & 1); } else { dataValue = Convert.ToInt16(dataValue >> dataposition & 0); } //新发送的值 ushort[] datas2 = new ushort[1]; ModbusConvert.SetShort(datas2, 0, dataValue); master.WriteSingleRegister(byte.Parse(device.IO_DEVICE_ADDRESS), offset, datas2[0]); } else { Int16 WriteValue = Int16.Parse(value); ushort[] buff = new ushort[1]; ModbusConvert.SetShort(buff, 0, WriteValue); master.WriteSingleRegister(byte.Parse(device.IO_DEVICE_ADDRESS), offset, buff[0]); } } break; case Modbus_Type.无符号整数32位: { uint WriteValue = uint.Parse(value); ushort[] buff = new ushort[2]; ModbusConvert.SetUInt(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(device.IO_DEVICE_ADDRESS), offset, buff); } break; case Modbus_Type.符号整数32位: { int WriteValue = int.Parse(value); ushort[] buff = new ushort[2]; ModbusConvert.SetInt(buff, 0, WriteValue); master.WriteMultipleRegisters(byte.Parse(device.IO_DEVICE_ADDRESS), offset, buff); } break; } } break; } } } } } catch { return(false); } return(true); }
/// <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); }