//异步处理报警逻辑(汉王数据接入使用) public async void AsyncHandleAlarmPolicies1(string deviceId, string air, string curValue, DateTime now) { RetDeviceInfo deviceInfo = new RetDeviceInfo(); RetDeviceItemInfo itemInfo = new RetDeviceItemInfo(); using (MonitoringEntities device = new MonitoringEntities()) { try { var searchDevice = device.D_Devices.Where(s => s.DeviceLabel == deviceId).FirstOrDefault(); if (searchDevice != null) { deviceInfo.ID = searchDevice.ID; deviceInfo.Name = searchDevice.Name; deviceInfo.DeviceLabel = searchDevice.DeviceLabel; var searchDeviceItem = device.D_DevicesItem.Where(s => s.DeviceID == searchDevice.ID && s.PropertyLabel == air).FirstOrDefault(); if (searchDeviceItem != null) { itemInfo.ID = searchDeviceItem.ID; itemInfo.Name = itemInfo.Name; itemInfo.PropertyLabel = itemInfo.PropertyLabel; } } } catch (Exception e) { log.ErrorFormat("内部错误:{0},{1}", e.Message, e.StackTrace); } var result = await HandleAlarmPolicies1(deviceInfo, itemInfo, curValue, now); } }
/// <summary> /// 启动设备的MQTT监听服务 /// </summary> /// <param name="item"></param> public static void StartUpDeviceService(RetDeviceInfo item) { // 物接入 if (item.ConnectType == "0") { //判断物接入的方式 IoTHubConfigurationModel model = new IoTHubConfigurationModel(); model.ID = long.Parse(item.IoTHubID); DeviceMonitoringApi deviceApi = new DeviceMonitoringApi(); var conf = deviceApi.GetIoTHubConnection(model); if (conf.Code == -1) { //throw new Exception("获取IoTHub连接信息失败" + conf.Msg); log.Error("获取IoTHub连接信息失败" + conf.Msg + " ;model ID" + model.ID); return; } RetIoTHubConfiguration connectInfo = (RetIoTHubConfiguration)conf.Data; long ioTHubID = long.Parse(item.IoTHubID); //==================== //=====直接接入======= //==================== if (connectInfo.Type == "1") { try { MqttClientService service = MqttServiceContainer.Instance.GetMqttServiceByConnectID(ioTHubID); //订阅该设备下的相关属性TOPIC BatchSubMessage(item, service); log.InfoFormat("[MQTT] Device: {0},Service Enable.", item.Name); } catch (Exception e) { log.Error("获取MQTT Client出错:" + e.Message, e); } } //========================== //==研华网关的设备直连方式== //========================== else if (connectInfo.Type == "3") { try { MqttClientService service = MqttServiceContainer.Instance.GetMqttServiceByConnectID(ioTHubID); //订阅该设备下的相关属性TOPIC //todo: 暂时使用remark字段存储订阅的topic service.SubscribeMessage(item.Remark); log.InfoFormat("[MQTT] Device: {0},Service Enable.", item.Name); } catch (Exception e) { log.Error("获取MQTT Client出错:" + e.Message, e); } } } }
/// <summary> /// 批量取消订阅 /// </summary> /// <param name="deviceInfo"></param> /// <param name="service"></param> private static void BatchUnsubMessage(RetDeviceInfo deviceInfo, MqttClientService service) { List <string> toSubList = new List <string>(); if (null != deviceInfo.DeviceItems && deviceInfo.DeviceItems.Count > 0) { foreach (var deviceItem in deviceInfo.DeviceItems) { toSubList.Add(deviceInfo.DeviceLabel + "/" + deviceItem.PropertyLabel); } } service.batchUnsubscribeMaessage(toSubList); }
/// <summary> /// 处理报警逻辑(汉王数据接入使用) /// 1.是否命中报警策略 /// 2.记录流水 /// 3.发送消息 /// </summary> /// <param name="deviceInfo"></param> /// <param name="itemInfo"></param> /// <param name="curValue"></param> /// <param name="now"></param> /// <returns></returns> private Task <int> HandleAlarmPolicies1(RetDeviceInfo deviceInfo, RetDeviceItemInfo itemInfo, string curValue, DateTime now) { int result = -1; using (AlertPoliciesEntities alert = new AlertPoliciesEntities()) { var alertInfo = alert.A_AlarmStrategy.Where(s => (s.DeviceID == deviceInfo.ID) && (s.DeviceItemId == itemInfo.ID) && (s.Active == true)).FirstOrDefault(); if (null != alertInfo) { if (isHitPolicies(curValue, alertInfo.Compare, alertInfo.Threshold)) { log.InfoFormat("[MQTT]Hit Policies,topic:{0}/{1},curValue:{2},compare:{3},theshold:{4}.", deviceInfo.DeviceLabel, itemInfo.PropertyLabel, curValue, alertInfo.Compare, alertInfo.Threshold); HistoryAlertPoliciesBLL historyBLL = new HistoryAlertPoliciesBLL(); HistoryAlertPoliciesModel model = new HistoryAlertPoliciesModel() { DeviceID = deviceInfo.ID.ToString(), DeviceItemID = itemInfo.ID.ToString(), StrategyID = alertInfo.ID.ToString(), Value = curValue, AlarmTime = now, EndTime = now.AddSeconds(1), OrgID = alertInfo.OrgID.ToString(), }; historyBLL.AddHistoryAlertPolicies(model); // 发送消息通知 UserApi api = new UserApi(); GetMessageInfoParameter messageModel = new GetMessageInfoParameter() { Type = "2", // 报警预警 Tittle = "【设备报警通知】" + deviceInfo.Name + itemInfo.Name + "报警!", Text = "<p>您好:</p><p class='ql-indent-1'>" + deviceInfo.Name + "(设备)" + itemInfo.Name + "(属性)当前数值为" + curValue + ",已触发预设报警策略,请及时处理异常!</p><p><br></p><p class='ql-align-right'>设备在线监测平台</p>", OrgID = alertInfo.OrgID.ToString() }; var userApi = api.AddAlarmMessage(messageModel); if (userApi.Code != 0) { log.ErrorFormat(userApi.Data); } } } } return(new Task <int>(() => result)); }
/// <summary> /// 将实时数据记录到TSDB /// </summary> /// <param name="deviceInfo"></param> /// <param name="itemInfo"></param> private void RecordToTsdb(RetDeviceInfo deviceInfo, RetDeviceItemInfo itemInfo, string curValue, DateTime now) { decimal value; try { value = Convert.ToDecimal(curValue); // 如果不能转成数字,则不存储到TSDB中。 } catch (Exception e) { log.ErrorFormat("内部错误:{0},{1}", e.Message, e.StackTrace); return; } DeviceMonitoringApi deviceApi = new DeviceMonitoringApi(); IoTHubConfigurationModel parameter = new IoTHubConfigurationModel(); parameter.ID = long.Parse(deviceInfo.DataConnectID); var retDataConnect = deviceApi.GetDataConnect(parameter); if (retDataConnect.Code == -1) { log.Error("获取数据连接数据出错,ID:" + deviceInfo.DataConnectID); return; } RetDataConnectConfiguration dataConnect = retDataConnect.Data; Dictionary <string, string> tagMap = new Dictionary <string, string>(); foreach (var tag in deviceInfo.TagList) { tagMap.Add(tag.Key, tag.Value); } try { OpentsdbClient client = new OpentsdbClient("http://" + dataConnect.ServerAddress + ":" + dataConnect.ServerPort); client.putData(itemInfo.PropertyLabel, now, value, tagMap); } catch (Exception) { return; } }
/// <summary> /// 通用的监听方法 /// 工作内容: /// 1.根据Topic获取设备及属性实例。Topic规则:DeviceLabel/PropertyLabel /// 2.查询是否命中报警策略,如果有则记录报警信息 /// 3.将实时数据保存到默认的TSDB数据库中 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MqttService_OnMqttMessageNotify(object sender, MqttMessageNotifyEventArgs e) { log.InfoFormat("[MQTT]收到消息:客户端:{0},主题:{1},消息:{2},Qos:{3},保留:{4}", e.ClientId, e.MqttApplicationMessage.Topic, Encoding.UTF8.GetString(e.MqttApplicationMessage.Payload), e.MqttApplicationMessage.QualityOfServiceLevel, e.MqttApplicationMessage.Retain); string[] topicArry = e.MqttApplicationMessage.Topic.Split('/'); if (topicArry.Length == 2) { string deviceLabel = topicArry[0]; string propertyLabel = topicArry[1]; DateTime now = DateTime.Now; DeviceMonitoringApi deviceMonitoringApi = new DeviceMonitoringApi(); GetDeviceInfoParameter par = new GetDeviceInfoParameter(); RetDeviceInfo deviceInfo = null; RetDeviceItemInfo itemInfo = null; par.DeviceLabel = deviceLabel; var resDeviceInfo = deviceMonitoringApi.GetDeviceInfo(par); if (resDeviceInfo.Code != -1) { deviceInfo = resDeviceInfo.Data; itemInfo = deviceInfo.DeviceItems.Find(s => s.PropertyLabel == propertyLabel); if (null == itemInfo) { log.ErrorFormat("根据Topic获取设备属性信息出错,无法匹配报警策略,deviceLabel{0},propertyLabel{1}", deviceLabel, propertyLabel); return; } } else { log.Error("根据deviceLabel获取设备信息失败" + resDeviceInfo.Msg); return; } //异步处理报警逻辑 AsyncHandleAlarmPolicies(deviceInfo, itemInfo, Encoding.UTF8.GetString(e.MqttApplicationMessage.Payload), now); //保存到TSDB RecordToTsdb(deviceInfo, itemInfo, Encoding.UTF8.GetString(e.MqttApplicationMessage.Payload), now); } else { log.ErrorFormat("解析TOPIC:{0} 失败,不符合规则", e.MqttApplicationMessage.Topic); } }
/// <summary> /// 启用设备 /// </summary> /// <param name="deviceId"></param> public void EnableDevice(long deviceId) { DeviceMonitoringApi deviceMonitoringApi = new DeviceMonitoringApi(); GetDeviceInfoParameter par = new GetDeviceInfoParameter(); par.ID = deviceId.ToString(); RetDeviceInfo deviceInfo = null; var resDeviceInfo = deviceMonitoringApi.GetDeviceInfo(par); if (resDeviceInfo.Code != -1) { deviceInfo = resDeviceInfo.Data; StartUpDeviceService(deviceInfo); } else { log.Error("获取设备信息出错:" + resDeviceInfo.Msg); return; } }
/// <summary> /// 禁用设备的处理 /// </summary> /// <param name="id"></param> public void DisableDeivce(long deviceId) { DeviceMonitoringApi deviceMonitoringApi = new DeviceMonitoringApi(); GetDeviceInfoParameter par = new GetDeviceInfoParameter(); par.ID = deviceId.ToString(); RetDeviceInfo deviceInfo = null; var resDeviceInfo = deviceMonitoringApi.GetDeviceInfo(par); if (resDeviceInfo.Code != -1) { deviceInfo = resDeviceInfo.Data; if (MqttServiceContainer.Instance.IsClientExist(long.Parse(deviceInfo.IoTHubID))) { RetIoTHubConfiguration connectInfo = GetConnectInfoById(deviceInfo.IoTHubID); if (null != connectInfo) { if (connectInfo.Type == "1") { //设备直连,删除Topics BatchUnsubMessage(deviceInfo, MqttServiceContainer.Instance.GetMqttServiceByConnectID(long.Parse(deviceInfo.IoTHubID))); } else if (connectInfo.Type == "3") { //研华网关,删除remark中的topic MqttServiceContainer.Instance.GetMqttServiceByConnectID(long.Parse(deviceInfo.IoTHubID)).UnsubscribeMessage(deviceInfo.Remark); } } log.InfoFormat("[MQTT] Device {0},Service Disable.", deviceInfo.Name); } } else { log.Error("获取设备信息出错:" + resDeviceInfo.Msg); return; } }
/// <summary> /// 物接入(研华网关方式) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MqttService_OnYanhuaMessageNotify(object sender, MqttMessageNotifyEventArgs e) { try { log.InfoFormat("[MQTT]收到消息:客户端:{0},主题:{1},消息:{2},Qos:{3},保留:{4}", e.ClientId, e.MqttApplicationMessage.Topic, Encoding.UTF8.GetString(e.MqttApplicationMessage.Payload), e.MqttApplicationMessage.QualityOfServiceLevel, e.MqttApplicationMessage.Retain); string[] topicArry = e.MqttApplicationMessage.Topic.Split('/'); string orgId = topicArry[0]; //组织ID //报文转换为对象 YanHuaPayload yanhuaPayload; try { yanhuaPayload = JsonHelper.JsonToEntity <YanHuaPayload>(Encoding.UTF8.GetString(e.MqttApplicationMessage.Payload)); } catch (Exception ex) { // 转换对象失败,报文格式不对,直接放弃 log.ErrorFormat("[MQTT]解析报文格式失败:{0},{1}", ex.Message, ex.StackTrace); return; } foreach (var payVal in yanhuaPayload.values) { try { DateTime uploadtime = DateTime.ParseExact(payVal.time, "yyyyMMdd-HH:mm:ss", CultureInfo.InvariantCulture); DeviceMonitoringApi deviceMonitoringApi = new DeviceMonitoringApi(); GetDeviceInfoParameter par = new GetDeviceInfoParameter(); RetDeviceInfo deviceInfo = null; RetDeviceItemInfo itemInfo = null; par.OrgID = orgId; par.Phone = payVal.device_ip; var resDeviceInfo = deviceMonitoringApi.GetDeviceInfo(par); if (resDeviceInfo.Code != -1) { deviceInfo = resDeviceInfo.Data; itemInfo = deviceInfo.DeviceItems.Find(s => s.Name == payVal.operationValue); if (null == itemInfo) { log.ErrorFormat("根据Topic获取设备属性信息出错,device_ip{0},name{1}", payVal.device_ip, payVal.name); continue; } } else { log.Error("根据deviceLabel获取设备信息失败" + resDeviceInfo.Msg); continue; } //处理报警逻辑 AsyncHandleAlarmPolicies(deviceInfo, itemInfo, payVal.data, uploadtime); //保存到TSDB RecordToTsdb(deviceInfo, itemInfo, payVal.data, uploadtime); } catch (Exception ex) { log.ErrorFormat("内部错误:{0},{1}", ex.Message, ex.StackTrace); continue; } } } catch (Exception ex) { log.ErrorFormat("内部错误:{0},{1}", ex.Message, ex.StackTrace); return; } }
private async void AsyncHandleAlarmPolicies(RetDeviceInfo deviceInfo, RetDeviceItemInfo itemInfo, string curValue, DateTime now) { var result = await HandleAlarmPolicies(deviceInfo, itemInfo, curValue, now); }