Пред‐компиляция JS‐правил - d51x/openhab-docs-russian GitHub Wiki
Проблема
В версиях openHAB 4.0.x - 4.1.x (на 10.01.2024) есть небольшая проблема с компиляцией JS-правил/скриптов.
Проблема заключается в следующем - первый запуск правила/скрипта занимает до 20 сек в зависимости от сервера, на котором поднят openHAB. Повторный запуск правила/скрипта работает быстро и тут проблем нет.
На что влияет?
Если у вас есть какое-либо JS-правило/скрипт, например, включение света по кнопке, то после запуска openHAB и при нажатии на кнопку, чтобы включить свет, вам придется подождать до 20 сек, что может быть не приемлемо.
Вариант решения:
-
Создаем специальный JS-скрипт, который будет запускаться при старте системы на уровне
50 - Rule Engine Started
Наш скрипт среди всех правил будет искать только те, у которых есть тэг
precompile
и будет такие правила по очереди запускать на выполнение. -
Все правила с тэгом
precompile
должны в самом начале проверять состояние вспомогательного Item'aprecompileRules
(тип Switch).Если его стоятояние
ON
, то правило ничего не делает.Если его состояние
OFF
, то правило выполняет необходимую логику.
Побочные эфекты:
- более долгий запуск openHAB - каждое такое правило будет компилироваться
- усложнение правил - в каждом правиле на самом верхнем уровне должно быть условие с проверкой состояния служебного Item'a
Скрипт "Компиляция правил"
var precompileTag = 'precompile'; // тэг для правил, требующих предварительной компиляции
var precompileItem = 'precompileRules'; // служебный Item, требуется создать с типом Switch
var now = Java.type('java.lang.System');
const { ruleRegistry } = require('@runtime/RuleSupport');
let RuleManager = osgi.getService("org.openhab.core.automation.RuleManager");
var rulesToCompile = utils.javaSetToJsArray(ruleRegistry.getAll());
rulesToCompile = rulesToCompile.filter(r => RuleManager.isEnabled(r.getUID()) && utils.javaSetToJsArray(r.getTags()).includes(precompileTag));
console.info('rules to compile:', rulesToCompile.length > 0 ? rulesToCompile.length : 'no rules');
if(rulesToCompile.length > 0) {
items.getItem(precompileItem).sendCommand('ON');
console.info('⚒ Компиляция правил...');
rulesToCompile.forEach(r => {
var ts = now.currentTimeMillis();
rules.runRule(r.getUID(), {});
ts = now.currentTimeMillis() - ts;
console.info('⚒ Правило [', r.getUID(), '::', r.getName(), ' ] скомпилировано :: ', ts,' ms');
});
items.getItem(precompileItem).sendCommand('OFF');
}
Насройка правила
Результаты работы скрипта предварительной компиляции
Пример правила, требущего предварительной компиляции
if (items.getItem('precompileRules').state == 'OFF') { //пред-кмопиляция уже выполнилась
// do something
}