Альтернативный Alive

Материал из MajorDoMo инфо


Для определения "Живости" датчиков ZigBee я использую следующее решение. Код ниже можно вставить в сченарий, любой метод и придумать, как его периодически запускать. У меня же для этого создан объект DevicesStates в классе systemStates и прописал код ниже в методе checkState

//return;
// Запускаем раз в 5мин, иначе ретурн
$time = time();
$m = (int)date('i', $time);
if ($m%5 != 0) return;

$timeout = 90*60;
$devices = getObjectsByClass("Devices"); // Класс, в котором все проверяемые устройства. У вас скорее всего SDevices
$telegramtext = "";
$f=0;

foreach($devices as $device) {

  $batteryLevel  = gg($device['TITLE'].'.batteryLevel');
  $heartbeatUpdated = gg($device['TITLE'].'.heartbeatUpdated');
  $alive = gg($device['TITLE'].'.alive');
  $aliveTimeOut = gg($device['TITLE'].'.aliveTimeOut')*3600;
  if(!isset($aliveTimeOut)) $alive = $timeout;
     
  $batteryLow  = gg($device['TITLE'].'.batteryLow');
  if(!isset($batteryLow)) sg($device['TITLE'].'.batteryLow', 0);

  if ( $alive == 1 && $time - $heartbeatUpdated > $timeout ) {
      sg($device['TITLE'].'.alive', 0);
     $f=1;   
      $text =  "HB ". $heartbeatUpdated . " AL " .$alive ." Отвалился " . $device['TITLE']." ". getObject($device['TITLE'])->description . "\n";    
    //Say('Отвалился датчик ' . $device['TITLE'].' '. getObject($device['TITLE'])->description, 1);
      $this->setProperty('error', $text);
      DebMes($text, 'DeviceCheck');
      $telegramtext = $telegramtext . '\n' . $text;
      $yellow_state=1;
  }
  elseif ( $alive != 1 && $time - $heartbeatUpdated < $timeout ) {
 $f=1;     sg($device['TITLE'].'.alive', 1);
    
      $text = "HB ". $heartbeatUpdated . " AL " .$alive ." Появился " . $device['TITLE']." ". getObject($device['TITLE'])->description . "\n";   
    //Say($text, 1);
      //DebMes($text, 'DeviceCheck');
    //$this->setProperty('alive', 1);
      $telegramtext = $telegramtext . $text;
  }  
    // Мониторим батарейки
    if ( $batteryLow < 1 && isset($batteryLevel) && $batteryLevel < 60 && $batteryLevel >30 ) {
          sg($device['TITLE'].'.batteryLow', 1);
          $text = " Желтый, уровень заряда батарейки " . $batteryLevel ."% у " . $device['TITLE']." ". getObject($device['TITLE'])->description . "\n";
          $telegramtext = $telegramtext . $text;
          $this->setProperty('error', $text);
          $yellow_state=1;
        }
    if ( $batteryLow == 1 &&  isset($batteryLevel) && $batteryLevel < 30 && $batteryLevel >1 ) {
          sg($device['TITLE'].'.batteryLow', 2);
          $text = " Красный, уровень заряда батарейки " . $batteryLevel ."% у " . $device['TITLE']." ". getObject($device['TITLE'])->description . "\n";
          $telegramtext = $telegramtext . $text;
          $this->setProperty('error', $text);
          $red_state=1;
        }
}

if ($telegramtext != "" && $f==1 ) {
  include_once(DIR_MODULES . 'telegram/telegram.class.php');
  $telegram_module = new telegram();
  $telegram_module->sendMessageToAdmin($telegramtext);

  if ($red_state==1 ) {      
      $this->setProperty('stateColor',"red");
     $this->setProperty('stateTitle',"красный");
      $this->callMethod('stateChanged');
    }
  elseif ($yellow_state==1 ) {      
      $this->setProperty('stateColor',"yellow");
     $this->setProperty('stateTitle',"желтый");
      $this->callMethod('stateChanged');
    }
}

У меня к классовому свойству "batteryLevel" привязан метод "heartbeatUpdate", который пишет в свою очередь в свойство "heartbeatUpdated" тайм(). Потом раз в 5 минут запускается код выше и сверяет насколько давно обновлялся "heartbeatUpdated". Если больше "aliveTimeOut" (мне так нравится), то аларм в телеграмм "всё пропало".

Ну а батарейка устройства привязана в ZigBee2Mqtt к свойству "batteryLevel".... Устройства ксяоми сами раз в 55мин присылают всю информацию

У меня лично поправлено /scripts/cycle_states.php

...
  if (time() - $checked_time > 5*60 ) //было 10
        {
        $checked_time = time();
            for ($i = 0; $i < $total; $i++)
            {
                callMethod($objects[$i]['TITLE'] . '.checkState');
            }
        }
      
...