Альтернативный Alive
Для определения "Живости" датчиков 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');
}
}
...