Main

Мониторинг состояния системы

Важным аспектом функционирования системы управления Умным Домом является контроль состояния компонентов, её составляющих. В этой статье я покажу, каким образом можно организовать наглядный и эффективный контроль работы системы.

(Ремарка: ниже описывается процесс создания необходимых классов и методов, но, начиная с некоторой версии системы, эти данные уже созданы и готовы к использованию/модификации.)

Для вышеописанной задачи нам потребуется создать класс объектов systemStates. В этом классе мы будем создавать объекты "уровней состояния" (название условное, дальше будет понятней). Объектов будет несколько, т.к. они будут служить разным целям.

Уровень состояния это простая оценка качества состояния системы с той или иной точки зрения. Я выделил три основные показателя и добавил их как объекты созданного выше класса:

Comminication -- состояние систем связи

Security -- состояние систем безопасности

System -- состояние целостности функционирования системы

Для созданного выше класса systemStates добавляем следующие свойства:

stateColor -- условный цвет уровня

stateTitle -- название уровня

stateDetails -- детали текущего уровня состояния

Кроме того, добавляем следующие методы класса:

checkState -- метод проверки состояния системы по выбранному параметру

stateChanged -- метод, который будет вызываться в случае изменения состояния

Таким образом, мы создали три объекта и у каждого есть выше перечисленные свойства и методы. Для того, чтобы система могла за собой следить необходимо наполнить необходимым кодом методы checkState каждого из объектов, а так же организовать постоянный запуск этих методов. Последнее, кстати, уже встроено в систему в виде цикла /scripts/cycle_states.php, который автоматически запускается со стартом системы и ежесекундно запускает метод checkState для всех объектов класса systemStates, так что нам остаётся написать код метода checkState для каждого из созданных объектов.

Назначение кода checkState -- проверить какие-то показатели, принять решение о том, в каком состоянии находится система и установить соответствующий уровень.

Для начала реализуем проверку состояния коммуникаций. Считаем, что с ними всё в порядке, если есть соединение с интернетом и "пингуется" шлюз -- зелёный уровень. Если интернета нет, но шлюз доступен, то ставим жёлтый уровень. Если недоступен шлюз, то красный.

Для метода Communication.checkState установим следующий код:

Нажмите для отображения кода

$details=array();

$red_state=0;
$yellow_state=0;

if (!isOnline('Интернет')) { // в модуле "Устройства Online" должна быть запись с названием "Интернет"
 $yellow_state=1;
 $details[]="Нет доступа в интернет";
}

if (!isOnline('192.168.0.1')) {  // в модуле "Устройства Online" должна быть запись с IP-адресом либо названием "192.168.0.1"
 $red_state=1;
 $details[]="Не доступен шлюз и беспроводная сеть";
}

if ($red_state) {
 $state='red';
 $state_title='Красный'; 
} elseif ($yellow_state) {
 $state='yellow';
 $state_title='Жёлтый';  
} else {
 $state='green';
 $state_title='Зелёный';   
}

$this->setProperty('stateDetails',implode(". ",$details));

if ($this->getProperty('stateColor')!=$state) {
 $this->setProperty('stateColor',$state);
 $this->setProperty('stateTitle',$state_title);
 if ($state!='green') {
  say("Уровень системы связи изменился на ".$state_title.".");
  say(implode(". ",$details));
 } else {
  say("Уровень системы связи восстановился на ".$state_title);
 }
 $this->callMethod('stateChanged');
}

Дальше сделаем код для проверки уровня безопасности (Security.checkState)

Нажмите для отображения кода

$details=array();
$red_state=0;
$yellow_state=0;

if ((gg('sensorEntry.status')==0) && (gg('sensorGarage.status')==0)) {
 $yellow_state=1;
 $details[]="Ворота и гараж открыты";
} elseif (gg('sensorEntry.status')==0) {
 $yellow_state=1;
 $details[]="Ворота открыты.";
}

if (!isOnline("192.168.0.115")) {
 $yellow_state=1;
 $details[]="Камера на втором этаже недоступна";
}

if ((gg('ThisComputer.somebodyHome')==0) && (gg('sensorEntry.status')==0) && (gg('sensorGarage.status')==0)) {
 $red_state=1;
 $details[]="Дома никого нет, а ворота и гараж открыты";
}

if ($red_state) {
 $state='red';
 $state_title='Красный'; 
} elseif ($yellow_state) {
 $state='yellow';
 $state_title='Жёлтый';  
} else {
 $state='green';
 $state_title='Зелёный';   
}

$this->setProperty('stateDetails',implode(". ",$details));

if ($this->getProperty('stateColor')!=$state) {
 $this->setProperty('stateColor',$state);
 $this->setProperty('stateTitle',$state_title);
 if ($state!='green') {
  say("Уровень безопасности изменился на ".$state_title.".");
  say(implode(". ",$details));
 } else {
  say("Уровень безопасности восстановился на ".$state_title);
 }
 $this->callMethod('stateChanged');
}

И, наконец, код для контроля целостности системы (System.checkState)

Нажмите для отображения кода

$details=array();
$red_state=0;
$yellow_state=0;

$cycles=array('states'=>'цикл проверки состояния','main'=>'главный цикл','execs'=>'цикл запуска команд','scheduler'=>'цикл планировщика');
foreach($cycles as $k=>$v) {
 $tm=getGlobal('ThisComputer.cycle_'.$k.'Run');
 if (time()-$tm>5*60) {
  $red_state=1;
  $details[]="Остановлен ".$v;
 }
}

$cycles=array('ping'=>'цикл пинг','webvars'=>'цикл веб переменных','watchfolders'=>'цикл слежения за папками','rss'=>'цикл эр-эс-эс');
foreach($cycles as $k=>$v) {
 $tm=getGlobal('ThisComputer.cycle_'.$k.'Run');
 if (time()-$tm>10*60) {
  $yellow_state=1;
  $details[]="Остановлен ".$v;
 }
}

if (isOnline('Контроллер Arduino 2')!==1) {
 $red_state=1;
 $details[]="Недоступен исполнительный контроллер";
}

if (isOnline('Контроллер Arduino_RF_RCV')!==1) {
 $yellow_state=1;
 $details[]="Недоступен RF-приёмник";
}

$sensors=array();
$sensors['sensorHumidityRemote3']="датчик влажности в спальне";
$sensors['sensorKotel']="датчик температуры на котле";
$sensors['sensorZal']="датчик температуры в зале";
$sensors['sensorTempRemote1']="датчик температуры в гараже";
$sensors['sensorTempRemote2']="датчик температуры в спальне";
$sensors['ws']="модуль погодной станции";
foreach($sensors as $k=>$v) {
 if (!gg($k.'.alive')) {
  $yellow_state=1;
  $details[]="Не обновляется ".$v;
 }
}

if ($red_state) {
 $state='red';
 $state_title='Красный'; 
} elseif ($yellow_state) {
 $state='yellow';
 $state_title='Жёлтый';  
} else {
 $state='green';
 $state_title='Зелёный';   
}

$this->setProperty('stateDetails',implode(". ",$details));

if ($this->getProperty('stateColor')!=$state) {
 $this->setProperty('stateColor',$state);
 $this->setProperty('stateTitle',$state_title);
 if ($state!='green') {
  say("Уровень целостности системы изменился на ".$state_title.".");
  say(implode(". ",$details));
 } else {
  say("Уровень целостности системы восстановился на ".$state_title);
 }
 $this->callMethod('stateChanged');
}

Следующим шагом нам нужно сделать вывод состояния системы. Можем для этого использовать "Меню управления". Добавим новый элемент типа HTML-блок:

В поле Data необходимо поместить следующий код

Безопасность: <span style="color:%Security.stateColor%">%Security.stateTitle%</span> %Security.stateDetails%<br>
Система:  <span style="color:%System.stateColor%">%System.stateTitle%</span> %System.stateDetails%<br>
Связь:  <span style="color:%Communication.stateColor%">%Communication.stateTitle%</span> %Communication.stateDetails%

В итоге в меню мы будем видеть подобную картину:

Таким образом, получаем наглядную и оперативную сводку по состоянию системы.

Важное замечание: в виду того, что методы checkState вызываются каждую секунду, необходимо исключить использование "медленных" операций при опросе состояния систем, т.е. статусы подсистем (датчиков, модулей и т.п.) должны обновляться отдельно, а checkState их только проверяет и делает вывод об общем статусе.

 
 

Обсуждение

 

sergejey: Обсуждение страницы Мониторинг состояния системы

pdmitry2: Сергей, а как сделать аналогично этому $details=array(); $red_state=0; $yellow_state=0; if ((gg('sensorEntry.status')==0) && (gg('sensorGarage.status')==0)) { $yellow_state=1; $details[]="Ворота и гараж открыты"; } elseif (gg('sensorEntry.status')==0) { $yellow_state=1; $details[]="Ворота открыты."; } if (!isOnline("192.168.0.115")) { $yellow_state=1; $details[]="Камера на втором этаже недоступна"; } if ((gg('ThisComputer.somebodyHome')==0) && (gg('sensorEntry.status')==0) && (gg('sensorGarage.status')==0)) { $red_state=1; $details[]="Дома никого нет, а ворота и гараж открыты"; } if ($red_state) { $state='red'; $state_title='Красный'; } elseif ($yellow_state) { $state='yellow'; $state_title='Жёлтый'; } else { $state='green'; $state_title='Зелёный'; } $this->setProperty('stateDetails',implode(". ",$details)); if ($this->getProperty('stateColor')!=$state) { $this->setProperty('stateColor',$state); $this->setProperty('stateTitle',$state_title); if ($state!='green') { say("Уровень безопасности изменился на ".$state_title."."); say(implode(". ",$details)); } else { say("Уровень безопасности восстановился на ".$state_title); } $this->callMethod('stateChanged'); } но, для датчика температуры? Например, есть датчик со свойством temp_1.temp, как сделать, что бы если температура ниже 20 градусов, в меню управления висел красный статус, а как только температура поднимается выше 20 градусов, статус менялся бы на зелёный, ну и всё это с соответствующими уведомлениями. Поможете? ;)

sergejey: там в коде есть блок условий. например такое: if (!isOnline("192.168.0.115")) { $yellow_state=1; $details[]="Камера на втором этаже недоступна"; } можно заменить его на такое (или добавить под ним): if (getGlobal('temp_1.temp')<20) { $red_state=1; $details[]="Температура на датчике 1 ниже 20 градусов"; }

Satgate_M: Сергей, добрый день. Более менее разобрался, что за что отвечает, но никак не могу осилить обновление датчиков. внизу в коде есть параметр(где массив сенсоров задаем): .alive вот где надо создать это .alive и как его вызывать и что должно в нем быть чтобы сенсоры работали. По факту у меня сенсоры работают, но система пишет, что датчик не обновляется! Спасибо.

sergejey: Сергей, добрый день. Более менее разобрался, что за что отвечает, но никак не могу осилить обновление датчиков. внизу в коде есть параметр(где массив сенсоров задаем): .alive вот где надо создать это .alive и как его вызывать и что должно в нем быть чтобы сенсоры работали. По факту у меня сенсоры работают, но система пишет, что датчик не обновляется! Спасибо. Смотрите на моём профайле в коннекте как сделано. Если в кратце, то при обновления значения датчиков у меня устанавливается значение alive в 1 и задаётся таймер, который сбрасывает это значение в 0. Таким образом, если датчик регулярно присылает обновления, то alive будет всегда 1.

Satgate_M: Сергей, добрый день. Более менее разобрался, что за что отвечает, но никак не могу осилить обновление датчиков. внизу в коде есть параметр(где массив сенсоров задаем): .alive вот где надо создать это .alive и как его вызывать и что должно в нем быть чтобы сенсоры работали. По факту у меня сенсоры работают, но система пишет, что датчик не обновляется! Спасибо. Смотрите на моём профайле в коннекте как сделано. Если в кратце, то при обновления значения датчиков у меня устанавливается значение alive в 1 и задаётся таймер, который сбрасывает это значение в 0. Таким образом, если датчик регулярно присылает обновления, то alive будет всегда 1. В профайле нашел вроде эти alive, а вот какой код в них записан где можно посмотреть?

sergejey: вот, к примеру: http://c2n.me/6TBpaN.jpg

Satgate_M: Добавил в метод tempChanged и при изменении температуры почему-то ничего не происходит ни в alive ни в других полях ничего нет, только температура (снимок в приложении) И ни как не могу ни у кого получить как поменять статус системы со слов на разцоцветные иконки (антенна, шестерня и тп). Скриншоты ниже.

Satgate_M: и что это за параметр в таймере 30*60 например как перевести его в реальное время чтобы понимать период обновления?

sergejey: и что это за параметр в таймере 30*60 например как перевести его в реальное время чтобы понимать период обновления? 30*60 это 30 раз по 60 секунд, т.е. 30 минут

vladragor: уже разобрался...

Kiruxa: Добавил в метод tempChanged и при изменении температуры почему-то ничего не происходит ни в alive ни в других полях ничего нет, только температура (снимок в приложении) Добрый день! Как решил проблему? Данные идут от MQTT брокера. Метод TempChanged не срабатывает. Если зайти в настройки этого метода и выполнить вручную через консоль - Ошибка Parse error

Sergey2055: Всем привет.Подскажите пожалуйста каким образом можно поменять состояние системы security на другое в зависимости от какого то свойства. Те допустим свойство объекта "A" изменилось поменялся статус на красный до тех пор пока свойство объекта не восстановится на нужное. Все перерыл не могу понять как завязано.

skysilver: Все перерыл не могу понять как завязано.У класса SystemStates есть объект Security, а у него метод checkState. Данный метод вызывается в цикле каждые 5 секунд и в нем как раз идет проверка нужных свойств, и на их основе выставляется статус - зеленый, желтый или красный. Добавьте туда нужный вам код.

woow: "проблема связи: нет доступа в интернет" что может быть, по интернету как по внутренней сети, так и по наружной вхожу и управляю ею а почему она пишет что нет доступа?

rial2001: "проблема связи: нет доступа в интернет" что может быть, по интернету как по внутренней сети, так и по наружной вхожу и управляю ею а почему она пишет что нет доступа? Тоже периодически бывает. Проблема решается только перезагрузкой РОУТЕРА)

directman66: Тоже было такое на роутере асус с альтернативной прошивкой. Перешил заводскую прошивку и проблема исчезла. Я полагаю, слетает маршрутизация домашней сети.

woow: Как то мы не поняли друг друга. Связь системы МЖД с интернетом есть всё управляется и данные труда сюда ходят , только вот это сообщение на панели висит. Если толку от неё никакого, надо бы стереть.

skysilver: В админке в устройствах Online смени хост на другой. Я у себя ip dns яндекса вписал, норм работает.

woow: В админке в устройствах Online смени хост на другой. Я у себя ip dns яндекса вписал, норм работает. Извините, но где это находится (админке в устройствах Online)?

skysilver: Извините, но где это находится (админке в устройствах Online)?Тут _http://IP_MJD/admin.php?pd=pz_&md=panel&inst=&action=pinghosts

[ Обсудить на форуме ]

 

MajorDomo

Информация

Проекты

Партнёры

edit SideBar

 
 
 

 

Blix theme adapted by David Gilbert, powered by PmWiki