/// <summary> /// 返回服务器端接收的数据,此处主要将一个设备下的所有IO表数据统一获取后在一次性上传, /// </summary> /// <param name="server"></param> /// <param name="comm"></param> /// <param name="device"></param> /// <param name="para">为null,此参数不传递,根据用户驱动需要</param> /// <param name="receivedatas">接收的全部数据,要求在驱动中进行一次读取后返回</param> public static void CDriverDll_OnDataReceived(IO_SERVER server, IO_COMMUNICATION comm, IO_DEVICE device, byte[] receivedatas, string date, object sender) { //解析数据 var analysisTask = Task.Run(() => { try { if (device != null && device.DeviceDrive != null) { //清理已经接收完成的数据 for (int i = 0; i < device.IOParas.Count; i++) { device.IOParas[i].IORealData = null; } device.GetedValueDate = DateTime.Now; device.ReceiveBytes = receivedatas; #region 循环解析实时数据接收的每个参数 ScadaDeviceKernel Driver = (ScadaDeviceKernel)device.DeviceDrive; for (int i = 0; i < device.IOParas.Count; i++) { #region 解析开关量 模拟量 字符常量 数据 try { if (device.IOParas[i].IO_POINTTYPE == "模拟量" || device.IOParas[i].IO_POINTTYPE == "开关量" || device.IOParas[i].IO_POINTTYPE == "字符串量") { try { Driver.InitKernel(server, comm, device, device.IOParas[i], device.DriverInfo); IOData recdata = Driver.AnalysisData(server, comm, device, device.IOParas[i], receivedatas, Convert.ToDateTime(date), sender); if (recdata != null) { device.IOParas[i].IORealData = recdata; } } catch { device.IOParas[i].IORealData = null; } } } catch { } #endregion #region 解析关系数据库值 try { if (device.IOParas[i].IO_POINTTYPE == "关系数据库值" && device.IOParas[i].IO_DATASOURCE.Trim() != "") { RelationalDatabase rlation = new RelationalDatabase(device.IOParas[i].IO_DATASOURCE); string sql = rlation.GetSql(); string conn = rlation.ConnectString; switch (rlation.Database_Type) { case "SQL Server": { try { if (conn != "" && sql != "") { DbHelperSQL sqlHealp = new DbHelperSQL(); sqlHealp.connectionString = conn; DataSet ds = sqlHealp.Query(sql); if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { device.IOParas[i].IORealData = new IOData(); device.IOParas[i].IORealData.CommunicationID = device.IO_COMM_ID; device.IOParas[i].IORealData.ServerID = device.IO_SERVER_ID; device.IOParas[i].IORealData.ID = device.IO_DEVICE_ID; device.IOParas[i].IORealData.ParaName = device.IOParas[i].IO_NAME; device.IOParas[i].IORealData.ParaString = device.IOParas[i].IO_PARASTRING; device.IOParas[i].IORealData.ParaValue = ds.Tables[0].Rows[0]["value"].ToString(); device.IOParas[i].IORealData.QualityStamp = QualityStamp.GOOD; device.IOParas[i].IORealData.Date = Convert.ToDateTime(ds.Tables[0].Rows[0]["datetime"].ToString()); } } } catch { device.IOParas[i].IORealData = null; } } break; case "ORACLE": { try { if (conn != "" && sql != "") { DbHelperOra oracleHealp = new DbHelperOra(); oracleHealp.connectionString = conn; DataSet ds = oracleHealp.Query(sql); if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { device.IOParas[i].IORealData = new IOData(); device.IOParas[i].IORealData.CommunicationID = device.IO_COMM_ID; device.IOParas[i].IORealData.ServerID = device.IO_SERVER_ID; device.IOParas[i].IORealData.ID = device.IO_DEVICE_ID; device.IOParas[i].IORealData.ParaName = device.IOParas[i].IO_NAME; device.IOParas[i].IORealData.ParaString = device.IOParas[i].IO_PARASTRING; device.IOParas[i].IORealData.ParaValue = ds.Tables[0].Rows[0]["value"].ToString(); device.IOParas[i].IORealData.QualityStamp = QualityStamp.GOOD; device.IOParas[i].IORealData.Date = Convert.ToDateTime(ds.Tables[0].Rows[0]["datetime"].ToString()); } } } catch { device.IOParas[i].IORealData = null; } } break; case "MySql": { try { if (conn != "" && sql != "") { DbHelperMySQL mysqlHealp = new DbHelperMySQL(); mysqlHealp.connectionString = conn; DataSet ds = mysqlHealp.Query(sql); if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { device.IOParas[i].IORealData = new IOData(); device.IOParas[i].IORealData.CommunicationID = device.IO_COMM_ID; device.IOParas[i].IORealData.ServerID = device.IO_SERVER_ID; device.IOParas[i].IORealData.ID = device.IO_DEVICE_ID; device.IOParas[i].IORealData.ParaName = device.IOParas[i].IO_NAME; device.IOParas[i].IORealData.ParaString = device.IOParas[i].IO_PARASTRING; device.IOParas[i].IORealData.ParaValue = ds.Tables[0].Rows[0]["value"].ToString(); device.IOParas[i].IORealData.QualityStamp = QualityStamp.GOOD; device.IOParas[i].IORealData.Date = Convert.ToDateTime(ds.Tables[0].Rows[0]["datetime"].ToString()); double d = 0; if (double.TryParse(device.IOParas[i].IORealData.ParaValue, out d)) { device.IOParas[i].IORealData.DataType = typeof(double); } else { device.IOParas[i].IORealData.DataType = typeof(string); } } } } catch { device.IOParas[i].IORealData = null; } } break; } } } catch { } #endregion #region 解析计算值包含公式计算的 // try { if (device.IOParas[i].IO_POINTTYPE == "计算值") { if (device.IOParas[i].IO_FORMULA.Trim() != "") { device.IOParas[i].IORealData = new IOData(); try { device.IOParas[i].IORealData.QualityStamp = QualityStamp.GOOD; device.IOParas[i].IORealData.Date = DateTime.Now; device.IOParas[i].IORealData.ParaName = device.IOParas[i].IO_NAME; device.IOParas[i].IORealData.DataType = typeof(double); //替换关键字为数值 string formula = device.IOParas[i].IO_FORMULA; foreach (IO_PARA para in device.IOParas) { if (device.IOParas[i].IO_POINTTYPE != "字符串量" && device.IOParas[i].IO_POINTTYPE != "计算值" && device.IOParas[i].IORealData != null) { if (device.IOParas[i].IORealData.QualityStamp == QualityStamp.GOOD && device.IOParas[i].IORealData.ParaValue != "-9999" && device.IOParas[i].IORealData.ParaValue != "") { formula = formula.Replace(device.IOParas[i].IO_NAME, device.IOParas[i].IORealData.ParaValue); } } } if (formula != "") { //解析数学公式 device.IOParas[i].IORealData.ParaValue = AnalyzeCalculate.Calculate(device.IOParas[i].IO_FORMULA); double d = 0; if (double.TryParse(device.IOParas[i].IORealData.ParaValue, out d)) { device.IOParas[i].IORealData.DataType = typeof(double); } else { device.IOParas[i].IORealData.DataType = typeof(string); } } else { device.IOParas[i].IORealData.ParaValue = "-9999"; device.IOParas[i].IORealData.QualityStamp = QualityStamp.BAD; } } catch { device.IOParas[i].IORealData.QualityStamp = QualityStamp.BAD; device.IOParas[i].IORealData.Date = DateTime.Now; device.IOParas[i].IORealData.ParaName = device.IOParas[i].IO_NAME; } } else { device.IOParas[i].IORealData = null; } } } catch { } #endregion #region 进行量程转换 try { if (device.IOParas[i].IO_POINTTYPE == "模拟量") { if (device.IOParas[i].IORealData != null && device.IOParas[i].IO_ENABLERANGECONVERSION == 1 && device.IOParas[i].IORealData.QualityStamp == QualityStamp.GOOD) { if (device.IOParas[i].IORealData.ParaValue != "" && device.IOParas[i].IORealData.ParaValue != "-9999") { string value = ConvertParaTypeValue(device.IOParas[i].GetParaValueType(), device.IOParas[i].IORealData.ParaValue, double.Parse(device.IOParas[i].IO_RANGEMAX), double.Parse(device.IOParas[i].IO_RANGEMIN), double.Parse(device.IOParas[i].IO_MAXVALUE), double.Parse(device.IOParas[i].IO_MINVALUE)); device.IOParas[i].IORealData.ParaValue = value; } } } } catch { } #endregion #region 常量值 try { if (device.IOParas[i].IO_POINTTYPE == "常量值") { device.IOParas[i].IORealData = new IOData() { CommunicationID = device.IOParas[i].IO_COMM_ID, DataType = typeof(string), Date = device.GetedValueDate, ParaName = device.IOParas[i].IO_NAME, ParaString = device.IOParas[i].IO_PARASTRING, ParaValue = device.IOParas[i].IO_INITALVALUE, QualityStamp = QualityStamp.GOOD, ServerID = device.IOParas[i].IO_SERVER_ID }; } } catch { } #endregion } #endregion #region 将解析后的数据上传到数据中心服务器上 IO_DEVICE newDevice = device.Copy(); try { //将接收到的数据保存到实时缓存,主要用于批量上传,提高传输效率 receiveRealCache.Push(new ReceiveCacheObject() { DataString = RealDataDBUtility.GetRealDataCacheString(device) }); MonitorFormManager.ShowMonitorUploadListView(server, comm, device, "上传成功"); } catch (Exception emx) { ThrowExceptionToMain(emx); } //在事件接收窗体中显示接收的采集数据 if (OnMonitorReceive != null) { OnMonitorReceive(server, comm, newDevice, receivedatas); } #endregion #region 计算报警并上传 try { Task.Run(() => { List <IO_PARAALARM> res = new List <IO_PARAALARM>(); //将接收到的数据保存到实时缓存,主要用于批量上传,提高传输效率 receiveRealCache.Push(new AlarmCacheObject() { DataString = RealDataDBUtility.GetAlarmCacheString(device, out res) }); for (int i = 0; i < res.Count; i++) { MonitorFormManager.MonitorIODataAlarmShowView(server, comm, device, res[i], "上传成功"); } res.Clear(); res = null; }); } catch (Exception emx) { ThrowExceptionToMain(emx); } #endregion } } catch (Exception emx) { ThrowExceptionToMain(emx); } if (receivedatas != null && receivedatas.Length > 0) { AddLogToMainLog(device.IO_DEVICE_NAME + "接收到数据 DATA=" + CVT.ByteToHexStr(receivedatas)); } }); }
public static void InitMonitor() { commDriverBll = new Scada.Business.SCADA_DRIVER(); //开启日志保存服务 MonitorLogRun(); #region 创建通讯和设备驱动 int num = MonitorDataBaseModel.ProgressMaxNum + 4; //执行方法 #region 读取当前采集站工程数据 try { TaskOperator = TaskOperator.关闭; IOServer = MonitorDataBaseModel.IOServer; //创建驱动模块 for (int i = 0; i < MonitorDataBaseModel.IOCommunications.Count; i++) { if (MonitorDataBaseModel.IOCommunications[i].DriverInfo == null) { AddLogToMainLog("创建通道" + MonitorDataBaseModel.IOCommunications[i].IO_COMM_NAME.ToString() + @"[" + MonitorDataBaseModel.IOCommunications[i].IO_COMM_LABEL + @"]驱动失败,请在采集站中设置该通讯通道驱动!"); continue; } try { if (MonitorDataBaseModel.IOCommunications[i].CommunicateDriver == null) { continue; } else { ((ScadaCommunicateKernel)MonitorDataBaseModel.IOCommunications[i].CommunicateDriver).IsCreateControl = false; } AddLogToMainLog("创建通道" + MonitorDataBaseModel.IOCommunications[i].IO_COMM_NAME.ToString() + @"[" + MonitorDataBaseModel.IOCommunications[i].IO_COMM_LABEL + @"]驱动成功!"); ScadaCommunicateKernel driverDll = (ScadaCommunicateKernel)MonitorDataBaseModel.IOCommunications[i].CommunicateDriver; driverDll.SetUIParameter(MonitorDataBaseModel.IOCommunications[i].IO_COMM_PARASTRING); driverDll.IsCreateControl = false; driverDll.InitKernel(MonitorDataBaseModel.IOServer, MonitorDataBaseModel.IOCommunications[i], MonitorDataBaseModel.IOCommunications[i].Devices, MonitorDataBaseModel.IOCommunications[i].DriverInfo); driverDll.CommunctionClose += CDriverDll_CommunctionClose; driverDll.CommunctionContinue += CDriverDll_CommunctionContinue; driverDll.CommunctionPause += CDriverDll_CommunctionPause; driverDll.CommunctionStart += CDriverDll_CommunctionStart; driverDll.CommunctionStop += CDriverDll_CommunctionStop; driverDll.DeviceSended += CDriverDll_DeviceSended; driverDll.DeviceStatusChanged += CDriverDll_DeviceStatusChanged; driverDll.Exception += CDriverDll_Exception; driverDll.OnDataReceived += CDriverDll_OnDataReceived; driverDll.OnShowFormLog += CDriverDll_OnShowFormLog; AddLogToMainLog("准备创建该通道下的设备驱动....."); for (int d = 0; d < MonitorDataBaseModel.IOCommunications[i].Devices.Count; d++) { Scada.Model.IO_DEVICE device = MonitorDataBaseModel.IOCommunications[i].Devices[d]; try { if (MonitorDataBaseModel.IOCommunications[i].Devices[d].DriverInfo == null) { AddLogToMainLog("创建设备" + device.IO_DEVICE_LABLE.ToString() + @"[" + device.IO_DEVICE_NAME + @"]驱动失败,请在采集站中设置该设备驱动!"); continue; } ((ScadaDeviceKernel)device.DeviceDrive).IsCreateControl = false; ((ScadaDeviceKernel)device.DeviceDrive).ExceptionEvent += CDriverDll_ExceptionEvent; ((ScadaDeviceKernel)device.DeviceDrive).InitKernel(MonitorDataBaseModel.IOServer, MonitorDataBaseModel.IOCommunications[i], device, null, device.DriverInfo); } catch (Exception ex) { ThrowExceptionToMain(new Exception("创建设备" + MonitorDataBaseModel.IOCommunications[i].Devices[d].IO_DEVICE_LABLE.ToString() + @"[" + MonitorDataBaseModel.IOCommunications[i].Devices[d].IO_DEVICE_NAME + @"]驱动失败,!错误原因:" + ex.Message)); } } } catch (Exception ex) { ThrowExceptionToMain(new Exception("ERROR600001" + ex.Message)); } } #endregion //创建垃圾定时回收 ClearMemoryTimer = new System.Threading.Timer(delegate { ClearMemory(); }, null, 1000, 30000); } catch (Exception ex) { ThrowExceptionToMain(new Exception("ERROR600002" + ex.Message)); } #endregion receiveRealCache = new ReceiveRealCache(100, 3000); //批量上传实时数据 receiveRealCache.WillUpload = (List <ReceiveCacheObject> result) => { try { //定时从缓存区上传数据 var analysisTask = Task.Run(() => { RealDataDBUtility.UploadReal(result); }); return(analysisTask); } catch { return(null); } }; ///批量上传报警数据 receiveRealCache.WillUploadAlarm = (List <AlarmCacheObject> result) => { try { //定时从缓存区上传数据 var analysisTask = Task.Run(() => { RealDataDBUtility.UploadAlarm(result); }); return(analysisTask); } catch { return(null); } }; receiveRealCache.Read(); Start(); }