Сценарии - новая версия API
-
Команда this.exit() может применяться для прерывания сценария в любом его месте?
столкнулся с тем, что
if (device.isOff() ) this.exit() ; // если выключено - выйти из сценария
в основном теле сценария не работает - сценарий бодро шлепает по коду дальше.
В то же время this.exit() помещенная , например, в функцию таймера прерывает сценарий.
-
@alesle Да, Вы правы, внутри функции start this.exit() не работает. Чтобы завершить функцию start, достаточно сделать return.
this.exit() предназначен, чтобы завершить асинхронную деятельность сценария из функций - обработчиков (запущенных из start). Логика такая:
-
Метод start() вызывается, когда движок запускает сценарий (по триггерам, по расписанию, интерактивно) и тот становится активным.
-
Если внутри сценария просто последовательность действий, он отработает и сразу завершится (станет не активным). При следующем запуске он опять начнется со start(). Большая часть сценариев работает именно так и 99,9% времени находятся в неактивном состоянии. Напротив таких сценариев не бывает зеленых галочек в Рабочих сценариях.
-
Но если сценарий взводит таймеры и/или устанавливает слушателей событий, сценарий не завершается, а остается активным, следит за своими таймерами и устройствами "изнутри", запускает функции-обработчики как реакцию на отслеживаемые события. Пока сценарий активен (зеленая галочка), start по триггеру уже не работает.
Чтобы завершить такой сценарий, из обработчика нужно выполнить команду this.exit().
По этой команде все его таймеры и слушатели удаляются и сценарий станет не активным. При следующем запуске опять выполнится start()
-
-
@intrapro ,
Огромное спасибо за разяснения!!!
-
Доброго времени суток! Пытаюсь реализовать вывод показаний скорости ветра. Датчик импульсный, 1 импульс= 2,4 км/час. Только как их преобразовать в скорость? Вероятно нужен сценарий, где выводятся показания счетчика за отведенное время (секунда, минута, час) и происходит его обнуление. Если кто решал подобную задачу, прошу поделиться!
-
@sergeyygr, думаю, что нужно делать так же как для счётчика газа. Писал об этом - тут
Главное верно определить вес импульса чтобы получить значения сразу в м/с или км/ч.
Хотя мне не до конца понятен принцип работы такого датчика. Он самостоятельно каждую секунду выдает сколько то импульсов, которые соответствуют скорости ветра в текущую единицу времени? Если так, то лучше "захватывать" эти показания сценарием, пересчитывать и присваивать датчику. Покажите что выдает отладчик на канале к которому подключен датчик?
Но опять же если все так как я написал выше, то можно пересчитывать показания с помощью формулы или через вкладку "Обработка значений" канала.
-
Пользователь @Alex_Jet написал в Сценарии - новая версия API:
@sergeyygr, думаю, что нужно делать так же как для счётчика газа. Писал об этом - тут
Главное верно определить вес импульса чтобы получить значения сразу в м/с или км/ч.
Хотя мне не до конца понятен принцип работы такого датчика. Он самостоятельно каждую секунду выдает сколько то импульсов, которые соответствуют скорости ветра в текущую единицу времени? Если так, то лучше "захватывать" эти показания сценарием, пересчитывать и присваивать датчику. Покажите что выдает отладчик на канале к которому подключен датчик?
Но опять же если все так как я написал выше, то можно пересчитывать показания с помощью формулы или через вкладку "Обработка значений" канала.Да, спасибо, так и настроил. Только нужна сумма импульсов в определенный промежуток времени, затем сброс показаний и опять сумма импульсов. Если считать метры в секунду, то вес импульса равен 0,667. Принцип датчика как счетчик воды, только в запросе m=2 не нужно, скорость большая, режим raw в канале контроллера выключен, дребезга нет. В общем задача сходна с тем, что нужно кроме общего расхода воды узнать ее расход в час и значение должно быть присвоено и постоянно обновляться в иконке датчика.
Датчик примерно такой - https://www.ab-log.ru/smart-house/weather-station/megad-2561-wind-sensors
-
@sergeyygr, так может быть просто сервером каждую секунду опрашивать канал 5 раз, вычисляя приращение счётчика канала. Далее сортировать значения, откидывать "боковые", усреднять оставшиеся - то есть будем получать "правильное" усреднённое значение в м/с каждые 5 секунд. Причем все это действие можно проводить раз в минуту/5минут.
Если вам удобнее км/ч, то в формуле можно усреднённое значение в м/с умножать на 3.6А вообще нужно в iH либо написать скрипт подобный или сделать то же средствами канала плагина MegaD.
Коллеги, @intrahouse, @intrapro, помогите с помощью iH разрешить вот такой скрипт:<? $last_cnt = 0; while(true) { $state = explode("/", file_get_contents("http://192.168.0.14/sec/?pt=7&cmd=get")); $cnt = $state[1]; if ( $last_cnt != $cnt ) $wind_speed = ($cnt - $last_cnt) * 0.0875 + 0.1; else $wind_speed = 0; echo $cnt." - $wind_speed m/s"; $last_cnt = $cnt; if ( $cnt > 1000 ) { $state = explode("/", file_get_contents("http://192.168.0.14/sec/?pt=7&cnt=0")); $last_cnt = 0; } sleep(1); } ?>
-
Пользователь @Alex_Jet написал в Сценарии - новая версия API:
@sergeyygr, думаю, что нужно делать так же как для счётчика газа. Писал об этом - тут
Главное верно определить вес импульса чтобы получить значения сразу в м/с или км/ч.
Хотя мне не до конца понятен принцип работы такого датчика. Он самостоятельно каждую секунду выдает сколько то импульсов, которые соответствуют скорости ветра в текущую единицу времени? Если так, то лучше "захватывать" эти показания сценарием, пересчитывать и присваивать датчику. Покажите что выдает отладчик на канале к которому подключен датчик?
Но опять же если все так как я написал выше, то можно пересчитывать показания с помощью формулы или через вкладку "Обработка значений" канала.Добрый день! А какое практическое значение имеет функция "Период опроса" в счетчике? Думаю в моем случае было бы полезно счетчику дать возможность обнулять с заданным периодом, опрашивать и выводить последние значение. Задача была решена!!!
-
@sergeyygr Добрый день!
Пока не совсем в теме по датчику. Но если воспроизвести скрипт от @Alex_Jet, то получится примерно так:- Опрашиваем датчик с заданным интервалом из сценария (в каналах опрос не нужен, т е период =0)
- По магической формуле считаем значение, используя значение счетчика
- Периодически сбрасываем счетчик
const WindSensor = Device('MyWindSensor'); script({ last_cnt:0, // Эту переменную нужно сохранять, поэтому ее выносим и далее исп как this.last_cnt boot() { return true; // Сценарий будет запускаться при старте сервера }, start() { this.resetCount(); // Взвести таймер - опрос раз в секунду, можно чаще (0.5 = 500 мсек) this.startTimer('T1', 1, 'onTimer'); }, resetCount() { // Передать запрос на сброс счетчика this.pluginCommand({unit:'megad1', command:{url:'/sec/?pt=7&cnt=0'}}); }, onTimer() { // Передать запрос на чтение, ответ придет в функцию getResponse this.pluginCommand({unit:'megad1', command:{url:'/sec/?pt=7&cmd=get', onResponse:'raw'}}, 'getResponse'); this.startTimer('T1', 1, 'onTimer'); // Следующий запрос }, getResponse(body) { // body = OFF/2 this.log('getResponse body= '+body); // Для отладки if (!body) return; const arr = body.split('/'); if (arr.length<2) { this.log('Ожидается значение счетчика после символа "/"'); return; // Ошибка, значение не получено } let cnt = arr[1]; if ( this.last_cnt != cnt ) { let wind_speed = (cnt - this.last_cnt) * 0.0875 + 0.1; this.last_cnt = cnt; this.assign(WindSensor, 'value', wind_speed); } if ( cnt > 1000 ) { this.resetCount(); this.last_cnt = 0; } } });
- Сценарий будет запускаться при старте сервера
- будет работать постоянно, потому что таймер все время перевзводится
- не имеет триггеров, то есть при необходимости его надо взводить/останавливать вручную (Запустить сценарий/ Остановить сценарий)
Потестируйте, возможно есть косяки или не все учтено
-
Пользователь @intrapro написал в Сценарии - новая версия API:
@sergeyygr Добрый день!
Пока не совсем в теме по датчику. Но если воспроизвести скрипт от @Alex_Jet, то получится примерно так:- Опрашиваем датчик с заданным интервалом из сценария (в каналах опрос не нужен, т е период =0)
- По магической формуле считаем значение, используя значение счетчика
- Периодически сбрасываем счетчик
const WindSensor = Device('MyWindSensor'); script({ last_cnt:0, // Эту переменную нужно сохранять, поэтому ее выносим и далее исп как this.last_cnt boot() { return true; // Сценарий будет запускаться при старте сервера }, start() { this.resetCount(); // Взвести таймер - опрос раз в секунду, можно чаще (0.5 = 500 мсек) this.startTimer('T1', 1, 'onTimer'); }, resetCount() { // Передать запрос на сброс счетчика this.pluginCommand({unit:'megad1', command:{url:'/sec/?pt=7&cnt=0'}}); }, onTimer() { // Передать запрос на чтение, ответ придет в функцию getResponse this.pluginCommand({unit:'megad1', command:{url:'/sec/?pt=7&cmd=get', onResponse:'raw'}}, 'getResponse'); this.startTimer('T1', 1, 'onTimer'); // Следующий запрос }, getResponse(body) { // body = OFF/2 this.log('getResponse body= '+body); // Для отладки if (!body) return; const arr = body.split('/'); if (arr.length<2) { this.log('Ожидается значение счетчика после символа "/"'); return; // Ошибка, значение не получено } let cnt = arr[1]; if ( this.last_cnt != cnt ) { let wind_speed = (cnt - this.last_cnt) * 0.0875 + 0.1; this.last_cnt = cnt; this.assign(WindSensor, 'value', wind_speed); } if ( cnt > 1000 ) { this.resetCount(); this.last_cnt = 0; } } });
- Сценарий будет запускаться при старте сервера
- будет работать постоянно, потому что таймер все время перевзводится
- не имеет триггеров, то есть при необходимости его надо взводить/останавливать вручную (Запустить сценарий/ Остановить сценарий)
Потестируйте, возможно есть косяки или не все учтено
Спасибо!
Настроил, в иконке показания суммируются.
Вот отладчик.
Вот лог.
Вот иконка.
-
@sergeyygr
Что я делаю не так?
-
@sergeyygr А у вас тип устройства какой? Счетчик? Нужен обычный аналоговый датчик.
-
Пользователь @intrapro написал в Сценарии - новая версия API:
@sergeyygr А у вас тип устройства какой? Счетчик? Нужен обычный аналоговый датчик.
Все заработало! Спасибо за это существенное уточнение!
-
@sergeyygr Хорошо, что заработало. А скорость то считает правильно? Датчик непростой
-
Пользователь @intrapro написал в Сценарии - новая версия API:
@sergeyygr Хорошо, что заработало. А скорость то считает правильно?
Эталонного измерителя нет). Только формула в паспорте
-
Пользователь @sergeyygr написал в Сценарии - новая версия API:
Пользователь @intrapro написал в Сценарии - новая версия API:
@sergeyygr Хорошо, что заработало. А скорость то считает правильно?
Эталонного измерителя нет). Только формула в паспорте
Считает - это сейчас КЛЮЧЕВОЙ результат!!!
-
Пользователь @sergeyygr написал в Сценарии - новая версия API:
Пользователь @sergeyygr написал в Сценарии - новая версия API:
Пользователь @intrapro написал в Сценарии - новая версия API:
@sergeyygr Хорошо, что заработало. А скорость то считает правильно?
Эталонного измерителя нет). Только формула в паспорте
Считает - это сейчас КЛЮЧЕВОЙ результат!!!
Если будет время, опишите задачу и решение в разделе Решения пользователей
Будем пользоваться
-
Пользователь @intrahouse написал в Сценарии - новая версия API:
Пользователь @sergeyygr написал в Сценарии - новая версия API:
Пользователь @sergeyygr написал в Сценарии - новая версия API:
Пользователь @intrapro написал в Сценарии - новая версия API:
@sergeyygr Хорошо, что заработало. А скорость то считает правильно?
Эталонного измерителя нет). Только формула в паспорте
Считает - это сейчас КЛЮЧЕВОЙ результат!!!
Если будет время, опишите задачу и решение в разделе Решения пользователей
Будем пользоватьсяЗакончу, настрою и выложу с фотками.
-
@intrapro, ИМХО нужно все же не каждую секунду опрашивать канал, а 1 раз в минуту/5 минут делать 5 измерений и усреднять их. Наверное, это можно сделать с помощью "Функции обработки" в канале?
-
@Alex_Jet, сценарий воспроизводит предложенный вами вариант скрипта php, там идет опрос каждую секунду (while(true) { file_get_contents ... sleep(1)} и периодически сброс счетчика на MegaD
Если можно опрашивать реже и усреднять - не проблема, усреднятьможно и в сценарии. Без сценария непонятно как сбрасывать счетчик, поэтому в канале опроса нет