/// <summary> /// 定时保存值到历史记录 /// </summary> /// <param name="client"></param> /// <param name="device"></param> static void saveValueOnTime_Thread(MyDriverClient client, Device device) { if (client.SaveOnTimeInfos.Count == 0) { return; } Task.Run(() => { while (client.Released == false) { foreach (var itemInfo in client.SaveOnTimeInfos) { if (itemInfo.CurrentValue != itemInfo.SaveValue && (DateTime.Now - itemInfo.SaveTime).TotalSeconds >= itemInfo.PointObj.DevicePoint.ValueOnTimeChangeSetting) { WriteHistory(itemInfo.PointObj.DevicePoint, itemInfo.CurrentValue); itemInfo.SaveValue = itemInfo.CurrentValue; itemInfo.SaveTime = DateTime.Now; } } Thread.Sleep(1000); } }); }
static void start() { try { if (hisDB != null) { lock (hisDB) { hisDB.CommitTransaction(); hisDB.Dispose(); } hisDB = null; } using (SysDB db = new SysDB()) { var sysSetting = db.SystemSetting.FirstOrDefault(); if (string.IsNullOrEmpty(sysSetting.HistoryPath)) { return; } try { //目录不存在,创建目录 if (System.IO.Directory.Exists(sysSetting.HistoryPath) == false) { System.IO.Directory.CreateDirectory(sysSetting.HistoryPath); } HistoryDataPath = $"data source=\"{sysSetting.HistoryPath.Replace("\\", "/")}/history_data.db\""; hisDB = new DB.SunRiz(HistoryDataPath, Way.EntityDB.DatabaseType.Sqlite); LastHisTime = DateTime.Now; hisDB.BeginTransaction(); } catch { return; } var pointGroups = from m in db.DevicePoint where m.ValueRelativeChange == true || m.ValueAbsoluteChange == true || m.ValueOnTimeChange == true || m.IsAlarm == true group m by m.DeviceId into g select g; foreach (var pointArr in pointGroups) { var deviceId = pointArr.Key.GetValueOrDefault(); var device = db.Device.AsTracking().FirstOrDefault(m => m.id == deviceId); var driver = db.CommunicationDriver.AsTracking().FirstOrDefault(m => m.id == device.DriverID); MyDriverClient client = new MyDriverClient(driver.Address, driver.Port.Value); client.Points = (from m in pointArr select new MyDevicePoint(m)).ToArray(); AllClients.Add(client); string[] pointAddrs = new string[client.Points.Length]; for (int i = 0; i < client.Points.Length; i++) { pointAddrs[i] = client.Points[i].DevicePoint.Address; if (client.Points[i].DevicePoint.ValueOnTimeChange == true) { client.SaveOnTimeInfos.Add(new SaveOnTimeInfo() { PointObj = client.Points[i], PointId = client.Points[i].DevicePoint.id.Value, Interval = client.Points[i].DevicePoint.ValueOnTimeChangeSetting.GetValueOrDefault(), }); } } watchClient(client, device, pointAddrs); //启动定时保存的线程 saveValueOnTime_Thread(client, device); } } } catch (Exception ex) { using (Way.Lib.CLog log = new Way.Lib.CLog("HistoryAutoRec error ")) { log.Log(ex.ToString()); } } }
/// <summary> /// 实时监测设备值变化 /// </summary> /// <param name="client"></param> /// <param name="device"></param> /// <param name="pointAddrs"></param> static void watchClient(MyDriverClient client, Device device, string[] pointAddrs) { client.NetClient = client.AddPointToWatch(device.Address, pointAddrs, (addr, value) => { var myPoint = client.Points.FirstOrDefault(m => m.DevicePoint.Address == addr); if (myPoint != null) { var point = myPoint.DevicePoint; var jobj = GetJsonObject(point); double dblValue; value = SunRizDriver.Helper.Transform(jobj, value); try { dblValue = Convert.ToDouble(value); } catch { return; } if (point.Type == DevicePoint_TypeEnum.Digital) { //开关量,直接保存 WriteHistory(point, dblValue); } else if (point.ValueOnTimeChange == true) { //定时保存 var timeInfo = client.SaveOnTimeInfos.FirstOrDefault(m => m.PointId == point.id); if (timeInfo != null) { timeInfo.CurrentValue = dblValue; } } else if (point.ValueAbsoluteChange == true) { //绝对变化是指这个变量当前值与前一个历史值比较,变化超过设定数值后进行历史保存 if (myPoint.LastValue == null || Math.Abs(dblValue - myPoint.LastValue.GetValueOrDefault()) >= point.ValueAbsoluteChangeSetting) { WriteHistory(point, dblValue); myPoint.LastValue = dblValue; } } else if (point.ValueRelativeChange == true) { //相对变化是指这个变量当前值与前一个历史值比较,变化超过设定值(这个值是该变量量程的百分比)后进行历史保存 if (myPoint.LastValue == null) { myPoint.LastValue = dblValue; } else if (myPoint.LastValue == 0 || Math.Abs(dblValue - myPoint.LastValue.GetValueOrDefault()) * 100 / myPoint.LastValue >= point.ValueRelativeChangeSetting) { WriteHistory(point, dblValue); myPoint.LastValue = dblValue; } } if (point.IsAlarm == true) { SystemHelper.AutoBackAlarm(point.id.Value, dblValue); if (point.Type == DevicePoint_TypeEnum.Analog) { foreach (var lowAlarm in myPoint.LowAlarmConfig) { if (dblValue < lowAlarm.Value) { SystemHelper.AddAlarm(new Alarm() { Content = $"触发低{lowAlarm.Number}报警", Address = point.Name, AddressDesc = point.Desc, PointId = point.id, PointValue = dblValue, Priority = lowAlarm.Priority, Expression = "{0}<" + lowAlarm.Value }); break; } } foreach (var hiAlarm in myPoint.HiAlarmConfig) { if (dblValue > hiAlarm.Value) { SystemHelper.AddAlarm(new Alarm() { Content = $"触发高{hiAlarm.Number}报警", Address = point.Name, AddressDesc = point.Desc, PointId = point.id, PointValue = dblValue, Priority = hiAlarm.Priority, Expression = "{0}>" + hiAlarm.Value }); break; } } if (point.IsAlarmOffset == true) { if (Math.Abs(dblValue - point.AlarmOffsetOriginalValue.GetValueOrDefault()) > point.AlarmOffsetValue) { SystemHelper.AddAlarm(new Alarm() { Content = $"偏差报警", Address = point.Name, AddressDesc = point.Desc, PointId = point.id, PointValue = dblValue, Priority = point.AlarmOffsetPriority, Expression = "{0}-" + point.AlarmOffsetOriginalValue + ">" + point.AlarmOffsetValue + " or {0}-" + point.AlarmOffsetOriginalValue + "<-" + point.AlarmOffsetValue }); } } else if (point.IsAlarmPercent == true) { if (myPoint.LastValue == null) { myPoint.LastValue = dblValue; myPoint.LastValueTime = DateTime.Now; } else if (myPoint.LastValue == 0 || Math.Abs(dblValue - myPoint.LastValue.GetValueOrDefault()) * 100 / myPoint.LastValue > point.Percent) { if ((DateTime.Now - myPoint.LastValueTime).TotalSeconds < point.ChangeCycle) { SystemHelper.AddAlarm(new Alarm() { Content = $"变化率报警", Address = point.Name, AddressDesc = point.Desc, PointId = point.id, PointValue = dblValue, Priority = point.AlarmPercentPriority }); } myPoint.LastValue = dblValue; myPoint.LastValueTime = DateTime.Now; } } } else { if (point.AlarmValue == dblValue) { SystemHelper.AddAlarm(new Alarm() { Content = $"触发报警", Address = point.Name, AddressDesc = point.Desc, PointId = point.id, PointValue = dblValue, Expression = "{0}=" + point.AlarmValue }); } } } //System.Diagnostics.Debug.WriteLine($"name:{addr} value:{value}"); } }, (err) => { if (client.Released) { return; } Task.Run(() => { Thread.Sleep(2000); watchClient(client, device, pointAddrs); }); }); }