Exemplo n.º 1
0
        protected override bool InitCommunicateKernel(IO_SERVER server, IO_COMMUNICATION communication, List <IO_DEVICE> ioDevices, SCADA_DRIVER driver)
        {
            if (IsCreateControl)
            {
                CommunicationControl = new Modbus_Serial_Ctrl();
                if (communication != null)
                {
                    CommunicationControl.SetUIParameter(communication.IO_COMM_PARASTRING);
                }
            }
            Serial_PARA = new Modbus_Serial_PARA();
            if (communication != null)
            {
                comParaPack          = new ParaPack(communication.IO_COMM_PARASTRING);
                Serial_PARA.BaudRate = Convert.ToInt32(comParaPack.GetValue("波特率"));
                Serial_PARA.CollectFaultsInternal = Convert.ToInt32(comParaPack.GetValue("重试间隔"));
                Serial_PARA.CollectFaultsNumber   = Convert.ToInt32(comParaPack.GetValue("重试次数"));
                Serial_PARA.ContinueCollect       = comParaPack.GetValue("连续采集") == "1" ? true : false;
                Serial_PARA.DataBits             = Convert.ToInt32(comParaPack.GetValue("数据位"));
                Serial_PARA.ModbusType           = (ModbusType)Enum.Parse(typeof(ModbusType), comParaPack.GetValue("MODBUS类型"));
                Serial_PARA.OffsetInterval       = Convert.ToInt32(comParaPack.GetValue("偏移间隔"));
                Serial_PARA.PackMaxSize          = Convert.ToInt32(comParaPack.GetValue("包最大长度"));
                Serial_PARA.ReadTimeout          = Convert.ToInt32(comParaPack.GetValue("读超时时间"));
                Serial_PARA.RSTSendPreKeeyTime   = Convert.ToInt32(comParaPack.GetValue("发送前RTS保持时间"));
                Serial_PARA.RTSSendAfterKeeyTime = Convert.ToInt32(comParaPack.GetValue("发送后RTS保持时间"));
                Serial_PARA.RTSEnable            = comParaPack.GetValue("RTS") == "1" ? true : false;
                Serial_PARA.SerialCheck          = (SerialCheck)Enum.Parse(typeof(SerialCheck), comParaPack.GetValue("校验"));
                Serial_PARA.SerialPort           = comParaPack.GetValue("串口");
                Serial_PARA.SimulatorSerialPort  = comParaPack.GetValue("模拟器串口");
                Serial_PARA.SixCommmand          = comParaPack.GetValue("支持6号命令") == "1" ? true : false;
                Serial_PARA.SixteenCommmand      = comParaPack.GetValue("支持16号命令") == "1" ? true : false;;
                Serial_PARA.StopBits             = (StopBits)Enum.Parse(typeof(StopBits), comParaPack.GetValue("停止位"));
                Serial_PARA.WriteTimeout         = Convert.ToInt32(comParaPack.GetValue("写超时时间"));

                //构造获取数据命令的字节数组,Modbus
                for (int i = 0; i < this.IODevices.Count; i++)
                {
                    object   fragment  = new ModbusFragmentStore();
                    RealData mRealData = new RealData();
                    mRealData.Device = this.IODevices[i];
                    ScadaDeviceKernel driverDll = DeviceDrives.Find(x => x.DeviceDriverID == this.IODevices[i].DEVICE_DRIVER_ID);
                    if (driverDll != null)
                    {
                        driverDll.InitKernel(IOServer, IOCommunication, this.IODevices[i], null, this.IODevices[i].DriverInfo);
                        //IO_DEVICE_ADDRESS中存储的是DTU编号
                        mRealData.SlaveId = this.IODevices[i].IO_DEVICE_ADDRESS;
                        //数据库中系统编号
                        mRealData.DEVICEID = this.IODevices[i].IO_DEVICE_ID;
                        //获取下发命令的参数,注意此次要进心分段存储,因为modbus一次不能超过123个寄存器地址
                        mRealData.Fragment = (ModbusFragmentStore)fragment;
                        RealDevices.Add(mRealData);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 2
0
        //由于此处Para里面设置的可能是不同命令的IO参数,所以需要返回不同命令的实时获取的数据,此处不需要返回Byte字节数组
        public List <byte[]> GetDataCommandBytes(IO_SERVER server, IO_COMMUNICATION Communication, IO_DEVICE device, List <IO_PARA> paras, IO_PARA currentpara, ref object sender)
        {
            List <byte[]> cmmdBytes = new List <byte[]>();
            //必须Read的IO参数
            List <ModbusFragmentStore> modbusCodes = new List <ModbusFragmentStore>();

            for (int i = 0; i < paras.Count; i++)
            {
                ParaPack paraPack = new ParaPack(paras[i].IO_PARASTRING);
                if (!modbusCodes.Exists(x => x.StoredCode == paraPack.GetValue("内存区")) && paraPack.GetValue("内存区") != "")
                {
                    ModbusFragmentStore stored = new ModbusFragmentStore();
                    stored.StoredCode = paraPack.GetValue("内存区");
                    stored.Fragments  = new List <ModbusFragment>();
                    stored.Units      = new List <ushort>();
                    modbusCodes.Add(stored);
                }
                paraPack.Dispose();
                paraPack = null;
            }
            for (int i = 0; i < paras.Count; i++)
            {
                ParaPack paraPack = new ParaPack(paras[i].IO_PARASTRING);
                if (paraPack.GetValue("内存区") != "")
                {
                    if (modbusCodes.Exists(x => x.StoredCode == paraPack.GetValue("内存区")) && paraPack.GetValue("内存区") != "")
                    {
                        ModbusFragmentStore stored = modbusCodes.Find(x => x.StoredCode == paraPack.GetValue("内存区"));
                        if (paraPack.GetValue("偏置") != "")
                        {
                            ushort offset = 0;
                            if (ushort.TryParse(paraPack.GetValue("偏置"), out offset))
                            {
                                if (!stored.Units.Contains(offset))
                                {
                                    stored.Units.Add(offset);
                                }
                            }
                        }
                    }
                }
            }
            ModbusFragmentStore mainStored = new ModbusFragmentStore();

            //由于modbus获取寄存器最大数量是124个,所以要进行分段,最大线圈数量是1999个
            foreach (ModbusFragmentStore stored in modbusCodes)
            {
                stored.MakeFragment();
                mainStored.Fragments.AddRange(stored.Fragments);
            }
            //获取要解析的命令
            sender = mainStored;
            return(cmmdBytes);
        }
Exemplo n.º 3
0
        protected override bool InitCommunicateKernel(IO_SERVER server, IO_COMMUNICATION communication, List <IO_DEVICE> ioDevices, SCADA_DRIVER driver)
        {
            if (IsCreateControl)
            {
                CommunicationControl = new Modbus_UDP_Ctrl();
                if (communication != null)
                {
                    CommunicationControl.SetUIParameter(communication.IO_COMM_PARASTRING);
                }
            }
            Udp_PARA = new Modbus_TCP_PARA();
            if (communication != null)
            {
                TcpParaPack = new ParaPack(communication.IO_COMM_PARASTRING);
                Udp_PARA.CollectFaultsInternal = Convert.ToInt32(TcpParaPack.GetValue("重试间隔"));
                Udp_PARA.CollectFaultsNumber   = Convert.ToInt32(TcpParaPack.GetValue("重试次数"));
                Udp_PARA.ContinueCollect       = TcpParaPack.GetValue("重试") == "1" ? true : false;
                Udp_PARA.LocalTCP_Port         = TcpParaPack.GetValue("本地端口");
                Udp_PARA.LocalTCP_IP           = TcpParaPack.GetValue("本地IP");
                Udp_PARA.SimulatorTCP_Port     = TcpParaPack.GetValue("模拟设备端口");
                Udp_PARA.SimulatorTCP_IP       = TcpParaPack.GetValue("模拟设备IP");
                Udp_PARA.WriteTimeout          = int.Parse(TcpParaPack.GetValue("写超时时间"));
                Udp_PARA.ReadTimeout           = int.Parse(TcpParaPack.GetValue("读超时时间"));
                Udp_PARA.WriteBufferSize       = int.Parse(TcpParaPack.GetValue("写缓存"));
                Udp_PARA.ReadBufferSize        = int.Parse(TcpParaPack.GetValue("读缓存"));

                //构造获取数据命令的字节数组,Modbus
                for (int i = 0; i < this.IODevices.Count; i++)
                {
                    object   fragment  = new ModbusFragmentStore();
                    RealData mRealData = new RealData();
                    mRealData.Device = this.IODevices[i];
                    ScadaDeviceKernel driverDll = DeviceDrives.Find(x => x.DeviceDriverID == this.IODevices[i].DEVICE_DRIVER_ID);
                    if (driverDll != null)
                    {
                        driverDll.InitKernel(IOServer, IOCommunication, this.IODevices[i], null, this.IODevices[i].DriverInfo);
                        //IO_DEVICE_ADDRESS中存储的是DTU编号
                        mRealData.SlaveId = this.IODevices[i].IO_DEVICE_ADDRESS;
                        //数据库中系统编号
                        mRealData.DEVICEID = this.IODevices[i].IO_DEVICE_ID;
                        //获取下发命令的参数,注意此次要进心分段存储,因为modbus一次不能超过123个寄存器地址
                        //mRealData.ReadSendByte = driverDll.GetDataCommandBytes(this.IOServer, this.IOCommunication, this.IODevices[i], this.IODevices[i].IOParas, null, ref fragment);
                    }
                    mRealData.Fragment = (ModbusFragmentStore)fragment;
                    RealDevices.Add(mRealData);
                }
            }

            return(true);
        }
Exemplo n.º 4
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);
            }
        }
Exemplo n.º 5
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);
        }