告警判断框架

FsuOS App建议编写驱动时,使用UniDataDevice或者UniBufferDevice模板,此时用户只需要将告警判断代码写在

void RunCheckThreshold() override;

void Temperature2::RunCheckThreshold()
{
    //"温度传感器"
    CheckThreshold("value", "温度", value, signal_index_);
}

函数内,即可完成告警判断。

FsuOS的告警判断默认是采用告警线程池调度来执行的,如果对告警的实时性有要求,可以直接调用DoCheckThreshold函数,这个函数会直接使用采集线程池进行告警信号的判断,达到实时判断的效果。

但是要注意的是,CPU还是那个CPU,采集线程池执行的工作多了,实时性就会下降,甚至采集数据卡顿,刷新时间增长。

FsuOS 支持3种告警判断方式:

1)用户规则

用户通过在网页上对设备的信号设置告警规则的方式。

例如: 对温度驱动的value信号设置规则。

此时,驱动侧只需要调用:

CheckThreshold("value", "温度", value);

即可完成告警的判断。此时FsuOS会自行寻找用户配置的告警规则,进行判断。

2)程序自行判断

void CheckThresholdBool(int level, const std::string& key, const std::string &signal_id, const std::string &signal_name, const std::string& subject, bool value, uint16_t signal_index = 1);
CheckThresholdBool(LEVEL_2, "cyberMate_0", "621243003", "回风高温告警", "回风高温告警", cData.alert[0]==1, signal_index_++);

比如程序明确 cData.alert[0] == 1 的时候就要出告警。signal_index为0的时候,代表告警屏蔽。

3)联通B接口规则,电信B接口规则由于工作方式类似联通B接口规则,适配到联通B接口规则

使用联通B接口或者电信B接口的方式对驱动进行告警规则的下发,由于B接口对数据的引用是采用信号的方式,所以驱动侧要进行配合。

 if(levelMap_["110610050010"]) {
    CheckThresholdBool(levelMap_["110610050010"] , "110610050010", "110610050010", boost::lexical_cast<std::string>(cData.ai_value[0]), "48V蓄电池组电压过低 当前值:" + boost::lexical_cast<std::string>(cData.ai_value[0]), cData.ai_value[0] <= valueMap_["110610050010"], 1);
    std::cout<<"HR:"<<data_id_<<" 1106100500010 bat1:"<<cData.ai_value[0]<<" Bat1_XiaFa_agv:"<<valueMap_["110610050010"]<<" result:"<<(cData.ai_value[0] <= valueMap_["110610050010"])<<std::endl;
  }
  if(levelMap_["110610060010"]) CheckThresholdBool(levelMap_["110610060010"] , "110610060010", "110610060010", boost::lexical_cast<std::string>(cData.ai_value[0]), "48V蓄电池组电压超低 当前值:" + boost::lexical_cast<std::string>(cData.ai_value[0]), cData.ai_value[0] <= valueMap_["110610060010"], 1);
  if(levelMap_["110610040010"]) CheckThresholdBool(levelMap_["110610040010"] , "110610040010", "110610040010", boost::lexical_cast<std::string>(cData.ai_value[0]), "48V蓄电池组电压过高 当前值:" + boost::lexical_cast<std::string>(cData.ai_value[0]), cData.ai_value[0] >= valueMap_["110610040010"], 1);

levelMap_ 记录信号110610050010的告警等级,0为禁用。 valueMap_ 记录信号110610050010的告警阈值。

至于110610050010代表的是意义,就需要根据文档,当前110610050010代表过低阈值。

4) 由于同一个驱动面临多种不同的B接口告警信号不同的问题,因此建议采用以下结构进行告警的判断

参考电信B接口的配置例子:

<?xml version="1.0" encoding="utf-8"?>
<SU ID="00-14-97-3B-C4-44">
  <DeviceList>
    <Device Description="" DeviceHLType="2" DeviceID="2120001" DeviceName="1#">
      <Signal AlarmMeanings="低" NormalMeanings="正常" OptionID="4" SPID="211200050010" SPName="环境温度过低告警" SPType="1" Unit="℃"/>
      <Signal AlarmMeanings="" NormalMeanings="" OptionID="4" SPID="231200020010" SPName="环境湿度" SPType="3" Unit="%RH"/>
      <Signal AlarmMeanings="超高" NormalMeanings="正常" OptionID="4" SPID="211200040010" SPName="环境温度超高告警" SPType="1" Unit="℃"/>
      <Signal AlarmMeanings="过高" NormalMeanings="正常" OptionID="4" SPID="211200060010" SPName="环境湿度过高告警" SPType="1" Unit="%RH"/>
      <Signal AlarmMeanings="低" NormalMeanings="正常" OptionID="4" SPID="211200070010" SPName="环境湿度过低告警" SPType="1" Unit="%RH"/>
      <Signal AlarmMeanings="过高" NormalMeanings="正常" OptionID="4" SPID="211200030010" SPName="环境温度过高告警" SPType="1" Unit="℃"/>
      <Signal AlarmMeanings="" NormalMeanings="" OptionID="4" SPID="231200010010" SPName="环境温度" SPType="3" Unit="℃"/>
    </Device>
    <Device Description="" DeviceHLType="2" DeviceID="2120002" DeviceName="2#">
      <Signal AlarmMeanings="有告警" NormalMeanings="正常" OptionID="4" SPID="221200150010" SPName="水浸告警" SPType="2" Unit="%RH"/>
    </Device>
  </DeviceList>
</SU>
void GeneralTempHumid::RunCheckThreshold()
{
   
	  //"温度传感器"
	  CheckThreshold("value", "温度", cData.temperature, 1);
    CheckThreshold("humid", "湿度", cData.humid, 1);
    //B接口
    switch(b_mode_)
    {
        case 1:
        {
            //联通
            std::ostringstream ss;
            ss << "911143000" << std::setw(3) << std::setfill('0') << signal_index_;
            CheckAOReport(ss.str(), cData.temperature);
            
            CheckThreshold("911643001001", "温度", cData.temperature);
            break;
        }
        case 2:
        {
            //电信
            if(levelMap_["211200050010"])
                CheckThresholdBool(levelMap_["211200050010"] , "211200050010", "211200050010", "环境温度过低告警", "环境温度过低告警 当前值:" + boost::lexical_cast<std::string>(cData.temperature), cData.temperature < valueMap_["211200050010"], 1);
                
            if(levelMap_["211200040010"])
                CheckThresholdBool(levelMap_["211200040010"] , "211200040010", "211200040010", "环境温度超高告警", "环境温度超高告警 当前值:" + boost::lexical_cast<std::string>(cData.temperature), cData.temperature > valueMap_["211200040010"], 1);
                
            if(levelMap_["211200060010"])
                CheckThresholdBool(levelMap_["211200060010"] , "211200060010", "211200060010", "环境湿度过高告警", "环境湿度过高告警 当前值:" + boost::lexical_cast<std::string>(cData.humid), cData.humid > valueMap_["211200060010"], 1);
            
            if(levelMap_["211200070010"])
                CheckThresholdBool(levelMap_["211200070010"] , "211200070010", "211200070010", "环境湿度过低告警", "环境湿度过低告警 当前值:" + boost::lexical_cast<std::string>(cData.humid), cData.humid < valueMap_["211200070010"], 1);
            
            if(levelMap_["211200030010"])
                CheckThresholdBool(levelMap_["211200030010"] , "211200030010", "211200030010", "环境温度过高告警", "环境温度过高告警 当前值:" + boost::lexical_cast<std::string>(cData.temperature), cData.temperature > valueMap_["211200030010"], 1);
            break;
        }
    }
}

此时的b_mode_是SMDDevice自动向驱动传入的,在UniDataDevice里自动进行了解析,1代表联通,2代表电信,代码根据这个执行电信或者联通,或者其他的告警判断。