Как в системе MDM автоматически вызвать метод у объекта...

Использование системы в различных ситуациях, вопросы программирования сценариев.

Модератор: immortal

Velizar
Сообщения: 37
Зарегистрирован: Ср фев 15, 2017 10:54 pm
Благодарил (а): 9 раз
Поблагодарили: 7 раз

Как в системе MDM автоматически вызвать метод у объекта...

Сообщение Velizar » Ср фев 15, 2017 11:43 pm

Доброго времени суток форумчане :)

Я только начал знакомиться с системой МДМ поэтому не судите, если мой вопрос покажется вам банальным. Весь код на PHP я придумал сам и возможно он не оптимален...

Система МДМ очень интересная и мощная

Для проверки системы в действии я собрал ArduinoControllerWebServer, правда отключил библиотеки: Arduino.h, OneWire.h, DallasTemperature.h и весь связанный сними код - то есть у меня вышел только исполняемый контроллер, к выходам 3, 5, 6 - подключил по светодиоду с резистором (типа для эмуляции реле ...)

В системе был класс Relays со свойством: status и методами:

Код: Выделить всё

//PARENT refresh
$status=$this->getProperty("status");
if ($status) {
 $this->callMethod('turnOn');
} else {
 $this->callMethod('turnOff');
}

//PARENT switch
$status=$this->getProperty("status");
if ($status) {
 $this->callMethod('turnOff');
} else {
 $this->callMethod('turnOn');
}

//PARENT turnOff
$this->setProperty("status", 0);

//PARENT turnON
$this->setProperty("status", 1); 
я создал дочерний класс ArduinoWSRelays, добавил к нему еще свойства:board_pin, server_ip.

Создал три объекты:Relay1(Green), Relay2(Red), Relay3(Blue) класса ArduinoWSRelays
прописал для них свойства:
Relay1(Green).board_pin = 3
Relay1(Green).server_ip = 192.168.1.100
и т.д

Прописал для них методы:

Код: Выделить всё

//CHILD turnON
$cmdUrl = "http://".$this->getProperty('server_ip')."/command?".$this->getProperty('board_pin')."=ON";
getURL($cmdUrl, 0);
$this->setProperty("status", 1);

//CHILD turnOff
$cmdUrl = "http://".$this->getProperty('server_ip')."/command?".$this->getProperty('board_pin')."=OFF";
getURL($cmdUrl, 0);
$this->setProperty("status", 0);


//CHILD refresh
$cmdUrl = "http://".$this->getProperty('server_ip')."/command?".$this->getProperty('board_pin')."=STATUS";
$str = getURL($cmdUrl, 0);
$status = (int) explode("=", $str)[1];
$this->setProperty('status', $status);
Создал на сцене три кнопки. И все работает замечательно - нажимаю кнопку светодиод светит - нажимаю еще раз тухнет :)

Вопрос как сделать так чтобы метод refresh(CHILD refresh) вызывался автоматически через, например 2 секунды?

То есть если состояние одного из реле на сервере изменится, каким-то другим интерфейсом - МДМ знал об этом.

Я понимаю что можно запрограммировать Ардуино на отправку запроса - типа
http://192.168.1.100/objects/?object=Re ... &m=refresh

Но меня интересует именно как сделать автоматический вызов метода refresh(CHILD refresh)

Спасибо за ответ :)))
Последний раз редактировалось Velizar Чт фев 16, 2017 12:06 pm, всего редактировалось 1 раз.
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Как в системе MDM автоматически вызвать метод у объекта.

Сообщение DimSun75 » Чт фев 16, 2017 12:09 am

http://majordomo.smartliving.ru/Main/Pr ... ngSchedule

Наверное SetTimeOut то, что нужно будет
За это сообщение автора DimSun75 поблагодарил:
Velizar (Чт фев 16, 2017 1:17 pm)
Рейтинг: 1.16%
ipz
Сообщения: 238
Зарегистрирован: Чт ноя 26, 2015 10:54 pm
Благодарил (а): 38 раз
Поблагодарили: 45 раз

Re: Как в системе MDM автоматически вызвать метод у объекта.

Сообщение ipz » Чт фев 16, 2017 12:40 am

Если очень хочется можно сделать функцию, которая сама себя записывает в таймеры (закладка X-Ray->Timers)

Код: Выделить всё

     // Основной код этой функции
     ...
     // Записываем себя в таймеры с указанием задержки в секундах
     clearTimeOut("Название таймера");
     setTimeOut("Название таймера", "runScript('имя этой функции');", 2); // 2 - задержка в секундах
}
Будет ли это гарантированно каждые 2 секунды - большой вопрос (на моей RPi3 врядли)
А как это будет работать если ответ займет больше 2 секунд?
А как это понравится вебсерверу на Ардуине?

Правильное решение вы знаете. Хозяин барин.

Если система стоит на Unix - можно из cron'а запускать
За это сообщение автора ipz поблагодарил:
Velizar (Чт фев 16, 2017 1:17 pm)
Рейтинг: 1.16%
Velizar
Сообщения: 37
Зарегистрирован: Ср фев 15, 2017 10:54 pm
Благодарил (а): 9 раз
Поблагодарили: 7 раз

Re: Как в системе MDM автоматически вызвать метод у объекта.

Сообщение Velizar » Чт фев 16, 2017 12:05 pm

ipz писал(а):Если очень хочется можно сделать функцию, которая сама себя записывает в таймеры (закладка X-Ray->Timers)

Код: Выделить всё

     // Основной код этой функции
     ...
     // Записываем себя в таймеры с указанием задержки в секундах
     clearTimeOut("Название таймера");
     setTimeOut("Название таймера", "runScript('имя этой функции');", 2); // 2 - задержка в секундах
} 
Будет ли это гарантированно каждые 2 секунды - большой вопрос (на моей RPi3 врядли)
А как это будет работать если ответ займет больше 2 секунд?
А как это понравится вебсерверу на Ардуине?

Правильное решение вы знаете. Хозяин барин.

Если система стоит на Unix - можно из cron'а запускать

Интуитивно я понимаю, что нужно использовать какой-то таймер, но куда (и как) его нужно в МДМ прописывать в моем варианте...?
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Как в системе MDM автоматически вызвать метод у объекта.

Сообщение DimSun75 » Чт фев 16, 2017 2:40 pm

Как-то не до конца понимаю чего вы хотите. Если с частотой 2 секунды постоянно дергать метод, то это не очень хорошая идея. Я бы даже сказал плохая. Контроллер сам должен информировать сервер про изменение состояния реле, например если у контроллера есть физическая кнопка.

Ну и совет. Все эти гет-запросы не очень хороший метод коммуникации с оборудованием, особенно для новых разработок. Лучше, да даже mqtt более достойный вариант для этого.
Velizar
Сообщения: 37
Зарегистрирован: Ср фев 15, 2017 10:54 pm
Благодарил (а): 9 раз
Поблагодарили: 7 раз

Re: Как в системе MDM автоматически вызвать метод у объекта.

Сообщение Velizar » Чт фев 16, 2017 7:29 pm

DimSun75 писал(а):Как-то не до конца понимаю чего вы хотите. Если с частотой 2 секунды постоянно дергать метод, то это не очень хорошая идея. Я бы даже сказал плохая. Контроллер сам должен информировать сервер про изменение состояния реле, например если у контроллера есть физическая кнопка.

Ну и совет. Все эти гет-запросы не очень хороший метод коммуникации с оборудованием, особенно для новых разработок. Лучше, да даже mqtt более достойный вариант для этого.
Я знаком с системой MDM третий день, и мне не совсем понятно куда писать

Код: Выделить всё

setTimeOut("Название таймера", "runScript('имя этой функции');", 2); // 2 - задержка в секундах     
...

На сколько я понял нужно написать сценарий?... так как только в сценарии есть галочка - выполнять периодически:

Код: Выделить всё

// Основной код этой функции
$cmdUrl = "http://192.168.1.100/command?3=STATUS";
$str = getURL($cmdUrl, 0);
$status = (int) explode("=", $str)[1];
//$this->setProperty("Relay1(Green).status", $status);
setGlobal("Relay1(Green).status", $status);
//say("Hello from ArduinoWSRelaysRefreshTimer", 1);
// Записываем себя в таймеры с указанием задержки в секундах
clearTimeOut("ArduinoWSRelaysRefreshTimer");
setTimeOut("ArduinoWSRelaysRefreshTimer", "runScript('ArduinoWSRelaysRefresh');", 5); // 2 - задержка в секундах
 
Я так должен был сделать? Или как то иначе

Чем протокол MQTT лучший обычных GET запросов? Я планировал что Ардуино будет возвращать результаты JSON'om. Его будет просто обрабатывать через PHP...
Последний раз редактировалось Velizar Вт фев 21, 2017 3:16 pm, всего редактировалось 1 раз.
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Как в системе MDM автоматически вызвать метод у объекта.

Сообщение DimSun75 » Чт фев 16, 2017 8:08 pm

Еще раз повторю: очень плохая идея постоянно опрашивать состояние железки с сервера. Лишняя, никому не нужная нагрузка и на сервер, и на железку и на сеть. Железка сама должна сообщать серверу об изменении своего состояния. Таймеры здесь используются только для контроля выполнения команды. Объясню. Вы выдаете на железку команду и знаете, что она должна выполниться максимум за 10 секунд, например. Взводите таймер например на 11 секунд. Железка, выполнив команду, должна отрапортовать серверу, что команда исполнена. По приходу этого рапорта, сервер удаляет таймер. А вот если таймер сработает, значит нештатная ситуация, и по срабатыванию таймера запустится скрипт, который как-то буде реагировать на такую ситуацию.

У вас же ситуация такая, что после выдачи команды сервером проверять ничего нет смысла. Реле, минуя сервер, могут переключить раз в день. Все остальное время сервер впустую будет долбится на железку. А оно надо?

Что касается mqtt. Протокол специально создавался для таких вещей, поэтому подходит больше. Получается как: есть топит, ну например Rele1/Status Железка подписана на него и может публиковать в него состояние реле. На сервере, в модуле MQTT привязываем этот топик к свойству какого-нибудь объекта.Дальше, чтобы включить реле нужно всего лишь записать в свойство этого объекта "1". Если на железке есть кнопка, которая переключает реле, то по нажатию на нее, переключается реле и состояние публикуется в топике (Rele1/Status) ну и без нашего участия новое значение появляется в свойстве привязанного объекта на сервере. Кнопка может быть на другом устройстве, да хоть на нескольких. Главное, чтобы они были подписаны и публиковали в один и тот же топик. Неправда ли, это гораздо проще, чем с гет запросами? И писанины в коде даже наверное меньше будет.
За это сообщение автора DimSun75 поблагодарил:
Velizar (Вт фев 21, 2017 2:50 pm)
Рейтинг: 1.16%
ipz
Сообщения: 238
Зарегистрирован: Чт ноя 26, 2015 10:54 pm
Благодарил (а): 38 раз
Поблагодарили: 45 раз

Re: Как в системе MDM автоматически вызвать метод у объекта.

Сообщение ipz » Чт фев 16, 2017 10:36 pm

На сколько я понял нужно написать сценарий?... так как только в сценарии есть галочка - выполнять периодически:
В МДМ есть три непосредственных способа реализовать свой код на php:
Метод объекта
Сценарий
Внешний скрипт

Запускать этот код можно тоже разными способами
- из другого метода или сценария
-- runScript('имя сценария');
-- callMethod('Объект.метод')
-- Есть еще вариант для использования в методе объекта с указателем на себя $this->callMethod('метод')
- при изменении конкретного свойства, указав этот метод или сценарий в поле конкретного свойства у объекта`Запускать при изменении`
- по внешней ссылке вида http://localhost (искать в Wiki)
- вручную (для метода объекта на закладе `Методы` кнопкой `test`, там же ссылка на запуск из вне; для объекта поставить галочку `Запустить при сохранении` и нажать сохранить)
- может есть еще. Это то, что вспомнил...

Выполнять периодически - сценарий будет запускаться один раз в указанное время (по дням недели и времени - точно не помню)

Для четвертого дня в MDM, по-моему, многовато уже информации.

Добавлю к предыдущему сообщению:
Вы уже придумали как будете останавливать этот зацикленный процесс если что? )))))
За это сообщение автора ipz поблагодарил:
Velizar (Вт фев 21, 2017 2:49 pm)
Рейтинг: 1.16%
Velizar
Сообщения: 37
Зарегистрирован: Ср фев 15, 2017 10:54 pm
Благодарил (а): 9 раз
Поблагодарили: 7 раз

Re: Как в системе MDM автоматически вызвать метод у объекта.

Сообщение Velizar » Вт фев 21, 2017 3:16 pm

DimSun75 писал(а):Еще раз повторю: очень плохая идея постоянно опрашивать состояние железки с сервера. Лишняя, никому не нужная нагрузка и на сервер, и на железку и на сеть. Железка сама должна сообщать серверу об изменении своего состояния. Таймеры здесь используются только для контроля выполнения команды. Объясню. Вы выдаете на железку команду и знаете, что она должна выполниться максимум за 10 секунд, например. Взводите таймер например на 11 секунд. Железка, выполнив команду, должна отрапортовать серверу, что команда исполнена. По приходу этого рапорта, сервер удаляет таймер. А вот если таймер сработает, значит нештатная ситуация, и по срабатыванию таймера запустится скрипт, который как-то буде реагировать на такую ситуацию.

У вас же ситуация такая, что после выдачи команды сервером проверять ничего нет смысла. Реле, минуя сервер, могут переключить раз в день. Все остальное время сервер впустую будет долбится на железку. А оно надо?

Что касается mqtt. Протокол специально создавался для таких вещей, поэтому подходит больше. Получается как: есть топит, ну например Rele1/Status Железка подписана на него и может публиковать в него состояние реле. На сервере, в модуле MQTT привязываем этот топик к свойству какого-нибудь объекта.Дальше, чтобы включить реле нужно всего лишь записать в свойство этого объекта "1". Если на железке есть кнопка, которая переключает реле, то по нажатию на нее, переключается реле и состояние публикуется в топике (Rele1/Status) ну и без нашего участия новое значение появляется в свойстве привязанного объекта на сервере. Кнопка может быть на другом устройстве, да хоть на нескольких. Главное, чтобы они были подписаны и публиковали в один и тот же топик. Неправда ли, это гораздо проще, чем с гет запросами? И писанины в коде даже наверное меньше будет.
Спасибо, что познакомили с протоколом MQTT, и более-менее объяснили как использовать таймеры :)

По возможности делал так, чтобы компоненты системы общались между собой по протоколу HTTP. Он выбран из-за простоты, прозрачности и привычности/понятности. Чего не скажешь про MQTT.

Мои эксперименты с MQTT показали что для него нужен сервер (брокер)...
Без сервера устройства между собой общаться не смогут, если скажем он - зависнет...
МДМ для MQTT запускает дополнительный процесс cycle_mqtt.php, а также наверное - cycle_websockets.php, и постоянно их гоняет (плюс еще брокер)... На моем Windows компьютере (AMD A10-5800K 8GB RAM) это не ощутимо, чего не скажешь о raspberry pi на котором обычно устанавливают сервер.

Но вот работа в МДМ с MQTT гораздо понятнее и проще чем напрямую общаться по HTTP (парсить и т.д.)
DimSun75
Сообщения: 318
Зарегистрирован: Вс янв 01, 2017 8:32 pm
Откуда: Москва
Благодарил (а): 7 раз
Поблагодарили: 44 раза

Re: Как в системе MDM автоматически вызвать метод у объекта.

Сообщение DimSun75 » Вт фев 21, 2017 8:09 pm

Velizar писал(а):
По возможности делал так, чтобы компоненты системы общались между собой по протоколу HTTP. Он выбран из-за простоты, прозрачности и привычности/понятности. Чего не скажешь про MQTT.
Ну как по мне, то mqtt попроще и по прозрачнее будет.
Мои эксперименты с MQTT показали что для него нужен сервер (брокер)...
Без сервера устройства между собой общаться не смогут, если скажем он - зависнет...
Зависнуть может все. Но, не берусь быть экспертом, ни разу не слышал о нестабильности mosquitto
МДМ для MQTT запускает дополнительный процесс cycle_mqtt.php, а также наверное - cycle_websockets.php, и постоянно их гоняет (плюс еще брокер)... На моем Windows компьютере (AMD A10-5800K 8GB RAM) это не ощутимо, чего не скажешь о raspberry pi на котором обычно устанавливают сервер.
Это ерунда. Вторая малинка со всем этим работает и не кашляет. Сейчас в планах перетащить брокер на orange zero и шлюз в MySensors туда же, а мажорика на orange plus2. Шлюз в принципе готов, надо только перенастроить все. Есть даже некоторые мысли установить брокеры на обоих апельсинках и переключатся в случае падения одного из них, но все пока не продумаю до конца.
Но вот работа в МДМ с MQTT гораздо понятнее и проще чем напрямую общаться по HTTP (парсить и т.д.)
Вообще, сделал еще по работе для себя выводы, что специально заточенные протоколы гораздо эффективнее универсальных. Но это мое личное мнение. Я просто показал, что есть альтернативы, а решает конечно каждый сам.
Ответить