Сценарии - новая версия API
-
Можно попросить добавить в окно отладчика сценариев кнопку "Пробный запуск сценария"?
Сейчас "Пробный запуск" можно сделать из меню по кнопке в верхней части экрана, но при открытом отладчике эта кнопка становится disabled.
В итоге невозможно сделать РУЧНОЙ пробный запуск сценария с просмотром в отладчике.
Да, Вы правы, постараемся добавить в одной из ближайших версий
-
Кстати, по поводу:
1. Реализации "cron" для сценариев (запуск сценариев для проверки состояния устройств)
Будет в конце месяца для простых и мультисценариев (пока без блок-схем)
2. Доступности из сценариев "журнал устройств" (для принудительного запуска насосов/котлов/кранов/клапанов если их период простоя велик)
Эта возможность уже добавлена в последней версии 4.5.3 как функция устройства device.getLog(<count>)
Опциональный параметр count - количество записей.
Возвращаются последние записи по возрастанию времени в виде массива с полями: значение, флаг ошибки, метка времени
{val:"23.5", err:0, ts:1554076800000}
Получить последние 10 записей:
const logArr = dn.getLog(10); logArr.forEach(item => { this.log(JSON.stringify(item)); });
4. Доступности из сценариев пользовательских журналов (создавать журналы можно, но писать в них логи пока никак)
Концепция журналов будет пересматриваться, пока по срокам не ясно
По столбцам ID у объектов/зон/систем/устройств уже сообщал свое пожелание выше… хотя тут обнаружил, что система теперь запоминает расположение столбцов. То есть если столбцы перенести как нужно администратору системы, то они в таком виде и останутся при следующим заходе в pm?
Да, это работает довольно давно.
Запоминаются ширина и порядок столбцов. Настройки хранятся на сервере, для нового сеанса всегда используется последняя настройка.</count>
-
3. Доступности из сценариев данных по устройству из БД (для составления и отправки месячной сводки в управляющие компании)
Эта возможность добавлена в последней версии 4.5.3 в тестовом режиме.
this.dbread({table:'consumption',dn:'METER1,METER2', start:'2019-04-01', end:'2019-04-01 23:59'}, 'onReady');
Здесь результат сразу не возвращается, так как чтение происходит асинхронно. При получении данных будет вызвана функция сценария (здесь она называется onReady), в которой данные нужно обработать.
onReady(result) { this.log('Получено записей: '+result.length); result.forEach(item => { this.log(JSON.stringify(item)); }); }
Первый аргумент this.dbread - объект, содержащий критерии отбора данных:
<list>* table - имя таблицы. Показания счетчиков хранятся в таблице consumptiondn: ID устройства или список через запятую start: метка времени или строка, определяющая начало диапазона end: метка времени или строка, определяющая конец диапазона</list>
То есть можно задавать временные точки по разному
start:1554076800000 // timestamp start:Date.now()-3600000 // timestamp start:'2019-04-01' // string дата 0 часов start:'2019-04-01 22:00' // string дата время
Данные возвращаются в массиве, каждая запись содержит метку времени, ID устройства, значение:
03.04 18:16:00.910 log: {"id":723,"ts":1554289199000,"dn":"METER1","val":"970.8578"}
Надо иметь в виду, что запрашивание больших массивов информации и их длительная обработка внутри сценария может приводить к замедлению работы сервера в целом, так как сценарии выполняются в главном потоке сервера.
Конечно, с получением показаний счетчиков на текущую дату никакой проблемы не будет. Но аппетит, как водится, приходит
И почему бы не получить данные за год и посчитать что-нибудь этакое средневзвешенное…
Если стоит задача обработки больших массивов, целесообразно будет применение сервисных плагинов (аддонов), механизм и API которых в данный момент разрабатывается. По сути это объединение функциональности плагина (независимый модуль, выполняемый в отдельном потоке) и сценария (доступ к данным ядра на уровне устройств и таблиц, подписка на события)
Планируется в мае выпустить версию и опубликовать новое API плагинов.
Цель - дать возможность пользователям разрабатывать свои плагины для решения прикладных задач, когда функционала сценариев недостаточно. Есть также идея делать это интерактивно, по аналогии со сценариями, чтобы порог вхождения был пониже.
-
Ну прям все круто! "Respect и уважуха" к вашей компании! И просто спасибо:)
-
Показания нужно передавать 17 числа каждого месяца. Как сформировать отчёт и выслать в УК?
Не понятно. Про какой отчет идет речь?
Нужно ведь отправлять показания счетчиков?
-
Ну прям все круто! "Respect и уважуха" к вашей компании! И просто спасибо:)
Присоединяюсь! Тоже с восхищением отношусь к вашей работе и мгновенной обратной связи!
Коллеги, большое спасибо!
Ваша поддержка придает уверенность и силы в дальнейшей работе
-
На сайте в блоге опубликовали статью по отправке показаний счетчиков https://ih-systems.com/ru/send_meter/
Надеюсь, будет полезна.
-
Спасибо! Все отлично работает! Только в показаниях счетчиков электроэнергии, после запятой, число длинной с… километр :lol: А в настройках стоит 2 знака.
Надо использовать функции js:
const meter = Device("METER1_01"); script({ start() { //Сводка по газу let account = xxxxxx; let name = meter.name; let value = meter.value.toFixed(0); this.info("email", "GAS_SERVICE", account+ "*" +value); this.info("telegram", "OWNER", "Текущее показание '"+name+ "' - " +value+ " куб.м"); } });
-
Интересный вопрос - если нужно временно отключить выполнение скрипта по расписанию, то как это можно сделать? Если убрать все дни недели, то он запуститься в уже назначенное время? Предусмотрите, пожалуйста, возможность блокировки задания в расписании. Конечно кто-то скажет что можно удалить и т.д., но если это надо временно, то почему бы не иметь возможность просто блокировать выполнение?
То же, например, с блокировкой мультисценариев и блокировкой канала плагина Ping.
-
Вопрос правильный. Надо сделать.
-
@intrahouse:
Вопрос правильный. Надо сделать.
Отвечу сам на свой вопрос - если в сценарии не указать ни один день недели, то расписание срабатывает ежедневно в назначенное время.
-
Я имел ввиду то, что надо дать возможность временной блокировки пунктов расписания
-
@intrahouse:
Я имел ввиду то, что надо дать возможность временной блокировки пунктов расписания
Понятно! Я с этим тоже согласен.
Просто проверил - можно ли таким способом не запускать расписание? - ответ нет, нельзя.
-
Есть сценарий, вкл. полотенцесушитель, взводим таймер на определенное время:
/**
-
@name Вкл. полотенцесушителя на время
-
@desc Включает сушилку на заданное время
-
@version 4
*/
const lamp = Device("SOCKET1_4",[
{"name":"timeOff", "note":"Время работы, сек", "type":"number", "val":1800}
]);
startOnChange([lamp]);
script({
start() {
if (lamp.isOn()) {
this.startTimer("T1",lamp.getParam("timeOff"),"onTimerT1");
this.addListener(lamp, "onLamp");
}
},
onTimerT1() {
lamp.off();
this.exit();
},
onLamp() {
if (lamp.isOff()) {
this.stopTimer("T1");
this.exit();
}
}
});
Вроде всё работает, но обнаружил : при перезагрузке системы если таймер был взведен, устройство так и останется включенным. Как в этом случае поступить ?, может где-то прописать что должно быть вкл или выкл при перезагрузке ? или в сценарии как прописать что если после перезагрузки вкл, то снова взести таймер ?
-
-
Есть сценарий, вкл. полотенцесушитель, взводим таймер на определенное время:
Вроде всё работает, но обнаружил : при перезагрузке системы если таймер был взведен, устройство так и останется включенным. Как в этом случае поступить ?, может где-то прописать что должно быть вкл или выкл при перезагрузке ? или в сценарии как прописать что если после перезагрузки вкл, то снова взести таймер ?
Чтобы сценарий срабатывал при загрузке, нужно добавить функцию boot.
Эта функция на старте проверяет, нужно ли запустить сценарий
Если вернется true, то будет запущена функция start
Сценарий всегда будет срабатывать при перезагрузке
.... script({ boot() { return true; }, start() { ..... }, ...
Cработает только если устройство включено:
.... script({ boot() { return lamp.isOn(); }, start() { ..... }, ...
-
Есть блок-схема: лог, таймер, присваивание значения, но почему-то создается 4 таймера и значение присваивается только в одном случае. Не верно строится скрипт из блоксхемы. Причем блок "лог" пришлось добавить потому что нельзя завести 4 входящие линии в таймер. Можно это тоже поправить?
/** * @name TelegramControl * @desc * @version 4 */ const SENSORA15 = Device("SENSORA15"); const ACTOR5 = Device("ACTOR5"); const SWITCH1 = Device("SWITCH1"); startOnChange([SENSORA15]); script({ start() { if (SENSORA15.value == "/lightoff") { this.doAll({ type: '510' },"off"); this.log(``); this.startTimer("T1",1,"onTimerT1"); } if (SENSORA15.value == "/securityon") { ACTOR5.on(); this.log(``); this.startTimer("T2",1,"onTimerT2"); } if (SENSORA15.value == "/securityoff") { ACTOR5.off(); this.log(``); this.startTimer("T3",1,"onTimerT3"); } if (SENSORA15.value == "/openhalldoor") { SWITCH1.on(); this.log(``); this.startTimer("T4",1,"onTimerT4"); } }, onTimerT1() { SENSORA15.setParam("value",100); }, onTimerT2() { }, onTimerT3() { }, onTimerT4() { } })
-
Есть тригер : датчик температуры, значения до десятой, н.р 5.3 град. Сейчас тригер срабатывает при каждом изменении на 0.1 град. Как сделать чтобы он срабатывал по целым числам, т.е при изменении на один градус ? Можно загрубить значение при выводе с датчика, но это нежелательно.
-
Есть тригер : датчик температуры, значения до десятой, н.р 5.3 град. Сейчас тригер срабатывает при каждом изменении на 0.1 град. Как сделать чтобы он срабатывал по целым числам, т.е при изменении на один градус ? Можно загрубить значение при выводе с датчика, но это нежелательно.
Если делаете через JS, то напрашивается деление с остатком. Делите показание на единицу, если остаток равен нулю, то продолжаете выполнять сценарий
-
Есть тригер : датчик температуры, значения до десятой, н.р 5.3 град. Сейчас тригер срабатывает при каждом изменении на 0.1 град. Как сделать чтобы он срабатывал по целым числам, т.е при изменении на один градус ? Можно загрубить значение при выводе с датчика, но это нежелательно.
Как вариант - делать сравнение текущего значения с запомненным в start.
То есть скрипт будет срабатывать при изменении значения на датчике. Но в основной функции мы это значение округляем до целого, сравниваем с запомненным +-1 и выполняем свою функцию (doFunction), ну или делаем какие-то действия. Что-то типа этого:
const dt = Device("STEMP4_01"); startOnChange(temp); script({ temp_storage: 0; start() { let temp = Math.round(dt.value); if(temp < temp_storage - 1 || temp > temp_storage + 1) { this.temp_storage = temp; this.doFunction(); } else this.exit(); } });
-
temp_storage: 0; здесь выдает ошибку Unexpected token