Пред‐компиляция JS‐правил - d51x/openhab-docs-russian GitHub Wiki

Проблема

В версиях openHAB 4.0.x - 4.1.x (на 10.01.2024) есть небольшая проблема с компиляцией JS-правил/скриптов.

Проблема заключается в следующем - первый запуск правила/скрипта занимает до 20 сек в зависимости от сервера, на котором поднят openHAB. Повторный запуск правила/скрипта работает быстро и тут проблем нет.

На что влияет?

Если у вас есть какое-либо JS-правило/скрипт, например, включение света по кнопке, то после запуска openHAB и при нажатии на кнопку, чтобы включить свет, вам придется подождать до 20 сек, что может быть не приемлемо.

Вариант решения:

  1. Создаем специальный JS-скрипт, который будет запускаться при старте системы на уровне 50 - Rule Engine Started

    Наш скрипт среди всех правил будет искать только те, у которых есть тэг precompile и будет такие правила по очереди запускать на выполнение.

  2. Все правила с тэгом precompile должны в самом начале проверять состояние вспомогательного Item'a precompileRules (тип 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');
}

Насройка правила

image

Результаты работы скрипта предварительной компиляции

image

Пример правила, требущего предварительной компиляции

if (items.getItem('precompileRules').state == 'OFF') { //пред-кмопиляция уже выполнилась
  // do something 
}