コード例 #1
0
        public static string GetReportString(string dateTimeStr, float temperatureVal, ModbusDeviceInfo deviceInfo)
        {
            string reportStr = temperatureVal.ToString();
            // 室温的设备种类编码是004
            string deviceTypeStr = "004";
            string deviceSnStr = deviceInfo.ServiceArea.ToString().PadLeft(3, '0') + deviceInfo.SpotNumber.PadLeft(3, '0') + deviceTypeStr + deviceInfo.DeviceAddr.ToString().PadLeft(3, '0');
            string insertStr = @"INSERT INTO " + deviceInfo.DbTableName + @"(time_stamp, device_number, value_01" + @") VALUES('"
                                    + dateTimeStr + @"'," + deviceSnStr + @", " + reportStr + @")";

            return insertStr;
        }
コード例 #2
0
ファイル: ModbusDeviceInquirer.cs プロジェクト: gangjian/work
 /// <summary>
 /// 查询执行
 /// </summary>
 override public void DoInquiry()
 {
     if ((null != DeviceList) &&
         (0 != DeviceList.Count))
     {
         AppendUITextBox("\r\n>------------------------------->");
         AppendUITextBox(DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString());
         // 对列表中的各个设备, 逐一进行查询
         for (int i = 0; i < DeviceList.Count; i++)
         {
             ModbusDeviceInfo di = DeviceList[i];
             AppendUITextBox("开始查询 " + di.DeviceName);
             Thread inquiryThread = new Thread(delegate() { InquiryTask(di); });
             inquiryThread.Start();
             System.Threading.Thread.Sleep(500);
         }
     }
 }
コード例 #3
0
ファイル: WaterMeterInquirer.cs プロジェクト: gangjian/work
        /// <summary>
        /// 单个设备查询线程的执行过程
        /// </summary>
        /// <param name="deviceInfo"></param>
        override protected void InquiryTask(ModbusDeviceInfo deviceInfo)
        {
            string dateTimeStr             = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            TcpSocketCommunicator inquirer = new TcpSocketCommunicator();

            try
            {
                // 与设备模块进行连接(Connect)
                // 设定Receive的接收超时时间为3000毫秒
                AppendUITextBox("	开始连接: "+ deviceInfo.DeviceName);
                inquirer.Connect(deviceInfo.HostName, deviceInfo.PortNum, 3000);
                AppendUITextBox("	"+ deviceInfo.DeviceName + "连接成功!");
                System.Threading.Thread.Sleep(100);

                // 发送查询命令内容
                // 目标设备地址
                // 功能码: 0x03(读)
                // 寄存器地址: 0x0202
                // 读长度: 0x0002
                byte[] tmpBytes = { (byte)deviceInfo.DeviceAddr, 0x03, 0x02, 0x02, 0x00, 0x02 };

                UInt16 crc16       = CRC16(tmpBytes, 6);
                byte   crcLowByte  = (byte)(crc16 & 0x00FF);
                byte   crcHighByte = (byte)((crc16 & 0xFF00) >> 8);
                // 水表
                byte[] sendBytes = { (byte)deviceInfo.DeviceAddr, 0x03, 0x02, 0x02, 0x00, 0x02, crcLowByte, crcHighByte };

                // 向设备模块发送读数查询指令
                AppendUITextBox("	查询 "+ deviceInfo.DeviceName + " 指令发送!");
                inquirer.Send(sendBytes);

                // 接收设备模块返回的读数查询结果
                ReceiveData ir = inquirer.Receive();
                AppendUITextBox("	接收到 "+ deviceInfo.DeviceName + " 应答数据: " + ir.RcvLen.ToString() + " 字节.");
                if ((ir.RcvLen >= 1) &&
                    (deviceInfo.DeviceAddr != ir.RcvBytes[0]))
                {
                    AppendUITextBox("	"+ "收到的应答设备地址不一致: " + ir.RcvBytes[0].ToString());
                    return;
                }
                if (ir.RcvLen < 3)
                {
                    System.Diagnostics.Trace.WriteLine(@"收到数据不正确, 无长度位!");
                    return;
                }
                int data_len = ir.RcvBytes[2];
                if (ir.RcvLen < data_len + 3)
                {
                    System.Diagnostics.Trace.WriteLine(@"收到数据长度不正确!");
                    return;
                }
                string waterVolumeStr = "";
                for (int i = 3; i < 3 + data_len; i++)
                {
                    string valStr = string.Format("{0:X}", ir.RcvBytes[i]).PadLeft(2, '0');
                    waterVolumeStr += valStr;
                }
                int iWaterVolumeVal = Convert.ToInt32(waterVolumeStr, 16);
                // 首先读数要乘以放大倍率
                float waterVolumeVal = iWaterVolumeVal * deviceInfo.Magnification;
                // 然后除以量纲得到实际小数值
                float fValue          = waterVolumeVal / deviceInfo.Magnitude;
                float fWaterVolumeVal = fValue + deviceInfo.Adjustment;

                // 上报给服务器
                string insertStr = GetReportString(dateTimeStr, fWaterVolumeVal, deviceInfo);
                AppendUITextBox("	"+ deviceInfo.DeviceName + " : 读数值 = " + fValue.ToString() + " + " + deviceInfo.Adjustment.ToString() + " = " + fWaterVolumeVal.ToString());
                ReportToDBServer(insertStr, deviceInfo.DeviceName);
            }
            catch (Exception ex)
            {
                AppendUITextBox("	"+ deviceInfo.DeviceName + ": 查询失败!");
                System.Diagnostics.Trace.WriteLine(ex.ToString());
            }
            finally
            {
                inquirer.Close();
            }
        }
コード例 #4
0
ファイル: WaterMeterInquirer.cs プロジェクト: gangjian/work
        public static string GetReportString(string dateTimeStr, float waterVolumeVal, ModbusDeviceInfo deviceInfo)
        {
            string reportStr = waterVolumeVal.ToString();
            // 水表的设备种类编码是002
            string deviceTypeStr = "002";
            string deviceSnStr   = deviceInfo.ServiceArea.ToString().PadLeft(3, '0')
                                   + deviceInfo.SpotNumber.PadLeft(3, '0') + deviceTypeStr
                                   + deviceInfo.DeviceAddr.ToString().PadLeft(3, '0');

            string insertStr = @"INSERT INTO " + deviceInfo.DbTableName + @"(time_stamp, device_number, value_01, group_id" + @") VALUES('"
                               + dateTimeStr + @"'," + deviceSnStr + @", " + reportStr + ", " + deviceInfo.GroupId.ToString() + @")";

            return(insertStr);
        }
コード例 #5
0
        /// <summary>
        /// 单个电表查询线程的执行过程
        /// </summary>
        /// <param name="deviceInfo"></param>
        protected override void InquiryTask(ModbusDeviceInfo deviceInfo)
        {
            TcpSocketCommunicator inquirer = new TcpSocketCommunicator();
            try
            {
                // 与设备模块进行连接(Connect)
                // 设定Receive的接收超时时间为3000毫秒
                AppendUITextBox("	开始连接: " + deviceInfo.DeviceName);
                inquirer.Connect(deviceInfo.HostName, deviceInfo.PortNum, 3000);
                AppendUITextBox("	" + deviceInfo.DeviceName + "连接成功!");
                System.Threading.Thread.Sleep(100);
                // 向设备模块发送查询指令(Modbus协议)
                //  第一个字节是通信地址(设备号)
                //  第二个字节是功能码0x03(读数据)
                //  后面依次是读的起始地址0x0000和读长度0x004E(=78, 读到"正向(吸收)有功电能")
                //  最后两个字节是CRC16校验码
                byte[] tmpBytes = { (byte)deviceInfo.DeviceAddr, 0x03, 0x00, 0x00, 0x00, 0x4E };

                // 计算CRC校验码
                UInt16 crc16 = CRC16(tmpBytes, 6);
                byte crcLowByte = (byte)(crc16 & 0x00FF);
                byte crcHighByte = (byte)((crc16 & 0xFF00) >> 8);

                byte[] sendBytes = { (byte)deviceInfo.DeviceAddr, 0x03, 0x00, 0x00, 0x00, 0x4E, crcLowByte, crcHighByte };

                // 向设备模块发送Modbus读数查询指令
                AppendUITextBox("	查询 " + deviceInfo.DeviceName + " 指令发送!");
                inquirer.Send(sendBytes);

                // 接收设备模块返回的读数查询结果
                ReceiveData rd = inquirer.Receive();
                AppendUITextBox("	接收到 " + deviceInfo.DeviceName + " 应答数据: " + rd.RcvLen.ToString() + " 字节.");
                // 对应答数据进行检查, 返回的第一个字节应该跟设备地址号一致
                if (    (rd.RcvLen >= 1)
                    &&  (deviceInfo.DeviceAddr != rd.RcvBytes[0])    )
                {
                    AppendUITextBox("	" + "收到的应答设备地址不一致: " + rd.RcvBytes[0].ToString());
                    return;
                }

                float fValue;
                string insertStr = GetReportString(rd, deviceInfo, out fValue);
                if (null == insertStr)
                {
                    return;
                }
                AppendUITextBox("	" + deviceInfo.DeviceName + " : 读数值 = "
                    + fValue.ToString() + " + " + deviceInfo.Adjustment.ToString() + " = "
                    + (fValue + deviceInfo.Adjustment).ToString());
                // 上报给服务器
                ReportToDBServer(insertStr, deviceInfo.DeviceName);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.ToString());
                AppendUITextBox("	" + deviceInfo.DeviceName + " : 查询失败!");
            }
            finally
            {
                inquirer.Close();
            }
        }
コード例 #6
0
        public static string GetReportString(ReceiveData inquiryResult, ModbusDeviceInfo deviceInfo, out float fValue)
        {
            string reportStr = "";
            fValue = 0;
            List<DataUnitInfo> dataInfoList = ElectricMeterDataSetting.GetElectricMeterDataSetting();
            int total_flg = 0;	// 数据库表中用以标识该电表是否为"总表"的标志, 如果是总表, 那么不在表示用电量占比的饼图和柱状图中显示其用电量;
            if (-1 != deviceInfo.DeviceName.IndexOf(@"总表"))
            {
                total_flg = 1;
            }

            foreach (var dataInfo in dataInfoList)
            {
                // -5是因为要去掉前面三个字节(分别是设备码, 操作码03, 和读的长度)和最后两个字节(CRC校验)
                if (dataInfo.Offset < inquiryResult.RcvLen - 5 - 1)
                {
                    string dataStr = "0x";
                    // 越过前面三个字节
                    int idx = dataInfo.Offset + 3;
                    for (int i = 0; i < dataInfo.Length; i++)
                    {
                        dataStr += string.Format("{0:X}", inquiryResult.RcvBytes[idx]).PadLeft(2, '0');
                        idx++;
                    }
                    UInt32 val;
                    try
                    {
                        val = Convert.ToUInt32(dataStr, 16);
                        dataInfo.Value = val;
                        reportStr += ", " + val.ToString();
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Trace.WriteLine(ex.ToString());
                    }
                }
            }

            // 现在只把"正向(吸收)有功电能"即耗电量, 存到数据库表里
            string[] arr = reportStr.Split(',');
            string valueStr = arr[arr.Length - 4].Trim();
            int iValue;
            if (!int.TryParse(valueStr, out iValue))
            {
                return null;
            }
            // 读数值要乘以放大倍率
            float value = iValue * deviceInfo.Magnification;

            // 然后还要除以量纲得到浮点型小数值
            fValue = value / deviceInfo.Magnitude;
            // 加上校正值进行校正调整得到最终的用电量
            float realVal = fValue + deviceInfo.Adjustment;

            // 电表的设备种类编码是001
            string deviceTypeStr = "001";
            // 3位服务区编号 + 3位采集点位置编号 + 3位设备种类编号 + 3位设备地址 = 12位设备编号唯一确定一个具体的设备
            string deviceSnStr = deviceInfo.ServiceArea.ToString().PadLeft(3, '0')
                                + deviceInfo.SpotNumber.PadLeft(3, '0') + deviceTypeStr
                                + deviceInfo.DeviceAddr.ToString().PadLeft(3, '0');

            string insertStr = @"INSERT INTO " + deviceInfo.DbTableName + @"(time_stamp, device_number, value_01, total_flg, group_id" + @") VALUES('" + inquiryResult.TimeStamp + @"'" + @", '"
                                + deviceSnStr + @"'," + realVal.ToString() + ", " + total_flg.ToString() + ", " + deviceInfo.GroupId.ToString() + @")";

            return insertStr;
        }
コード例 #7
0
ファイル: ModbusDeviceInquirer.cs プロジェクト: gangjian/work
 protected virtual void InquiryTask(ModbusDeviceInfo deviceInfo)
 {
     AppendUITextBox("这里是基类的方法呀呀呀!!!!");
 }
コード例 #8
0
ファイル: Form1.cs プロジェクト: gangjian/work
        private List<ModbusDeviceInfo> CreateWaterTemperatureList()
        {
            List<ModbusDeviceInfo> waterTemperatureMeterList = new List<ModbusDeviceInfo>();
            foreach (ListViewItem item in listView5.Items)
            {
                if (!item.Checked)
                {
                    continue;
                }
                ModbusDeviceInfo deviceInfo = new ModbusDeviceInfo();
                string[] paraArr = new string[item.SubItems.Count];
                int idx = 0;
                foreach (ListViewItem.ListViewSubItem subitems in item.SubItems)
                {
                    paraArr[idx] = subitems.Text.Trim();
                    idx++;
                }
                int value;
                // 服务区编号
                deviceInfo.ServiceArea = Service_area_num;
                // 设备名称
                deviceInfo.DeviceName = paraArr[0];
                // DeviceSN
                deviceInfo.SpotNumber = paraArr[1];
                // 目标设备地址
                if (int.TryParse(paraArr[2], out value))
                {
                    deviceInfo.DeviceAddr = value;
                }
                // IP
                deviceInfo.HostName = paraArr[3];
                // 端口号
                if (int.TryParse(paraArr[4], out value))
                {
                    deviceInfo.PortNum = value;
                }
                // 数据库中对应的表名
                deviceInfo.DbTableName = Db_table_list[4];

                // 水温的量纲默认是10
                deviceInfo.Magnitude = 10;

                waterTemperatureMeterList.Add(deviceInfo);
            }
            return waterTemperatureMeterList;
        }
コード例 #9
0
ファイル: Form1.cs プロジェクト: gangjian/work
        private List<ModbusDeviceInfo> CreateWaterMeterList()
        {
            List<ModbusDeviceInfo> waterMeterList = new List<ModbusDeviceInfo>();
            foreach (ListViewItem item in listView4.Items)
            {
                if (!item.Checked)
                {
                    continue;
                }
                ModbusDeviceInfo deviceInfo = new ModbusDeviceInfo();
                string[] paraArr = new string[item.SubItems.Count];
                int idx = 0;
                foreach (ListViewItem.ListViewSubItem subitems in item.SubItems)
                {
                    paraArr[idx] = subitems.Text.Trim();
                    idx++;
                }
                int value;
                float fvalue;
                // 服务区编号
                deviceInfo.ServiceArea = Service_area_num;
                // 设备名称
                deviceInfo.DeviceName = paraArr[0];
                // DeviceSN
                deviceInfo.SpotNumber = paraArr[1];
                // 目标设备地址
                if (int.TryParse(paraArr[2], out value))
                {
                    deviceInfo.DeviceAddr = value;
                }
                // IP
                deviceInfo.HostName = paraArr[3];
                // 端口号
                if (int.TryParse(paraArr[4], out value))
                {
                    deviceInfo.PortNum = value;
                }
                // 读数放大倍率
                if (float.TryParse(paraArr[5], out fvalue))
                {
                    deviceInfo.Magnification = fvalue;
                }
                // 分组编号
                deviceInfo.GroupId = 0;	// 默认值是0
                if (int.TryParse(paraArr[6], out value))
                {
                    deviceInfo.GroupId = value;
                }
                float fAdjustment = 0;
                if (float.TryParse(paraArr[7], out fAdjustment))
                {
                    deviceInfo.Adjustment = fAdjustment;
                }
                // 数据库中对应的表名
                deviceInfo.DbTableName = Db_table_list[3];

                // 水表的量纲默认是10
                deviceInfo.Magnitude = 10;

                waterMeterList.Add(deviceInfo);
            }
            return waterMeterList;
        }
コード例 #10
0
        /// <summary>
        /// 单个设备查询线程的执行过程
        /// </summary>
        /// <param name="deviceInfo"></param>
        protected override void InquiryTask(ModbusDeviceInfo deviceInfo)
        {
            string dateTimeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            TcpSocketCommunicator inquirer = new TcpSocketCommunicator();
            try
            {
                // 与设备模块进行连接(Connect)
                // 设定Receive的接收超时时间为3000毫秒
                AppendUITextBox("	开始连接: " + deviceInfo.DeviceName);
                inquirer.Connect(deviceInfo.HostName, deviceInfo.PortNum, 3000);
                AppendUITextBox("	" + deviceInfo.DeviceName + "连接成功!");
                System.Threading.Thread.Sleep(100);

                // 发送查询命令内容
                // 帧头:0x10
                // 总字节数: 0x07
                // 目标地址: 4byte16进制数
                // IO功能编号: 0x0A PT100温度采集
                string deviceAddrStr = deviceInfo.DeviceAddr.ToString().PadLeft(8, '0');
                if (8 != deviceAddrStr.Length)
                {
                    return;
                }
                byte b1 = Convert.ToByte(deviceAddrStr.Substring(0, 2), 16);
                byte b2 = Convert.ToByte(deviceAddrStr.Substring(2, 2), 16);
                byte b3 = Convert.ToByte(deviceAddrStr.Substring(4, 2), 16);
                byte b4 = Convert.ToByte(deviceAddrStr.Substring(6, 2), 16);

                byte[] sendBytes = { 0x10, 0x07, b1, b2, b3, b4, 0x0a };

                // 向设备模块发送读数查询指令
                AppendUITextBox("	查询 " + deviceInfo.DeviceName + " 指令发送!");
                inquirer.Send(sendBytes);

                // 接收设备模块返回的读数查询结果
                ReceiveData ir = inquirer.Receive();
                AppendUITextBox("	接收到 " + deviceInfo.DeviceName + " 应答数据: " + ir.RcvLen.ToString() + " 字节.");
                // 室温返回的结果是字符串, 直接是以小数表示, 所以不用除以量纲
                string outStr = System.Text.Encoding.ASCII.GetString(ir.RcvBytes).Substring(0, ir.RcvLen);
                int idx = -1;
                string temperatureStr = "";
                // 加号表示零上温度,减号表示零下温度
                if (-1 != (idx = outStr.IndexOf('+')))
                {
                    temperatureStr = outStr.Substring(idx).Trim();
                }
                else if (-1 != (idx = outStr.IndexOf('-')))
                {
                    temperatureStr = outStr.Substring(idx).Trim();
                }
                else
                {
                    return;
                }
                float temperatureVal = 0;
                if (!float.TryParse(temperatureStr, out temperatureVal))
                {
                    return;
                }
                // 加上校正值进行校正调整得到最终的温度值
                float fValue = temperatureVal + deviceInfo.Adjustment;

                AppendUITextBox("	" + deviceInfo.DeviceName + " 返回值: " + temperatureStr + " + ("
                                    + deviceInfo.Adjustment.ToString() + ") = " + fValue.ToString());
                // 上报给服务器
                string insertStr = GetReportString(dateTimeStr, fValue, deviceInfo);
                AppendUITextBox("	" + deviceInfo.DeviceName + " : 读数值 = " + fValue.ToString());
                ReportToDBServer(insertStr, deviceInfo.DeviceName);

                // 判断温度值是否在正常区间内
                int alarmType = 0;
                if (0 != (alarmType = IsTemperatureOutOfRange(fValue)))
                {
                    AddTemperatureAlarmRecord(deviceInfo, alarmType, fValue);
                }
            }
            catch (Exception ex)
            {
                AppendUITextBox("	" + deviceInfo.DeviceName + ": 查询失败!");
                System.Diagnostics.Trace.WriteLine(ex.ToString());
            }
            finally
            {
                inquirer.Close();
            }
        }
コード例 #11
0
        /// <summary>
        /// 追加室温异常警报记录
        /// </summary>
        /// <param name="deviceInfo"></param>
        void AddTemperatureAlarmRecord(ModbusDeviceInfo deviceInfo, int alarmType, float alarmValue)
        {
            // date_time
            string dateTimeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            // sarea_id
            string sareaIdStr = deviceInfo.ServiceArea.ToString().PadLeft(3, '0');
            // spot_id
            string spotIdStr = deviceInfo.SpotNumber.ToString().PadLeft(3, '0');
            // device_type 室温固定是"004"
            string deviceTypeStr = "004";
            // device_id
            string deviceIdStr = deviceInfo.DeviceAddr.ToString().PadLeft(3, '0');
            string alarmTypeStr = string.Empty;
            if (alarmType > 0)
            {
                alarmTypeStr = @"高于上限";
            }
            else
            {
                alarmTypeStr = @"低于下限";
            }
            // alart_message
            string alarmMsgStr = Service_area_name + " " + deviceInfo.DeviceName + " 室温异常 : " + alarmTypeStr;
            // value_01 = alarmValue

            string insertStr = @"INSERT INTO " + "temperature_alarm_record"
                                + @"(date_time, sarea_id, spot_id, device_type, device_id, alarm_message, value_01"
                                + @") VALUES('" + dateTimeStr + @"','" + sareaIdStr + @"', '" + spotIdStr + @"', '"
                                + deviceTypeStr + @"', '" + deviceIdStr + @"', '" + alarmMsgStr + @"', " + alarmValue.ToString() + @")";
            WriteToDB(insertStr);
            if (!SaveToLocalFile(insertStr))
            {
                AppendUITextBox("	" + deviceInfo.DeviceName + " 室温异常" + " : 保存本地记录文件失败!");
            }
        }
コード例 #12
0
ファイル: ModbusDeviceInquirer.cs プロジェクト: gangjian/work
 virtual protected void InquiryTask(ModbusDeviceInfo deviceInfo)
 {
     AppendUITextBox("这里是基类的方法呀呀呀!!!!");
 }