Перейти к содержанию

Навигация

Rule Examples: различия между версиями

(не показано 10 промежуточных версий 4 участников)
Строка 1: Строка 1:
<languages/>
<languages/>
<translate>
<translate>
<!--T:250-->
<!--T:255-->
{{DISPLAYTITLE: Примеры правил}}
{{DISPLAYTITLE: Примеры правил}}


== Общая информация ==
== Общая информация ==
Здесь вы найдёте учебные примеры скриптов, написанных для движка правил [[wb-rules| wb-rules]].
Здесь вы найдёте учебные примеры скриптов, написанных для движка правил '''[[wb-rules| wb-rules]]'''.


Алгоритмы в примерах предельно просты и не учитывают многих факторов которые могут возникнуть в реальности. Поэтому используйте эту библиотеку только как учебный материал, а не источник готовых скриптов для реальных проектов.
Алгоритмы в примерах предельно просты и не учитывают многих факторов которые могут возникнуть в реальности. Поэтому используйте эту библиотеку только как учебный материал, а не источник готовых скриптов для реальных проектов.
== Виртуальное устройство ==
Виртуальное устройство можно использовать для объединения каналов, задания особой логики для устройства или просто так для красоты.
Пример ниже создаст виртуальное устройство с именем '''deviceName''' и двумя контролами '''value''' и '''state'''. А благодаря правилу с '''whenChanged''', значение контрола '''state''' будет менять в зависимости от значение контрола '''value'''.
<syntaxhighlight lang="ecmascript">
deviceName = 'my-virtual-device';
defineVirtualDevice(deviceName, {
    title: {'en': 'My Virtual Device', 'ru': 'Мое виртуальное устройство'} ,
    cells: {
      value: {
        title: {'en': 'Value', 'ru': 'Значение'},
        type: "range",
        value: 1,
        max: 3,
        min: 1
      },
      state: {
        title: {'en': 'State', 'ru': 'Состояние'},
        type: "value",
        value: 1,
        enum:{
          1: {'en': 'Normal', 'ru': 'В норме'},
          2: {'en': 'Warning', 'ru': 'Внимание'},
          3: {'en': 'Crash', 'ru': 'Авария'}} 
      },
    }
});
defineRule({
  whenChanged: deviceName+"/value",
  then: function (newValue, devName, cellName) {
dev[deviceName+"/state"] = newValue;
  }
});
</syntaxhighlight>


== Слежение за контролом == <!--T:20-->
== Слежение за контролом == <!--T:20-->
Строка 64: Строка 104:
   <!--T:32-->
   <!--T:32-->
}
}
});
</syntaxhighlight>
== Мастер-выключатель с восстановлением последнего состояния == <!--T:250-->
На вход контроллера подключен мастер-выключатель, который, при переключении, отключает все устройства, указанные в соответствующем правиле. При повторном нажатии на выключатель, устройствам возвращается первоначальное состояние.
Подключение осуществляется к контакту A1 и 5V на контроллере. При замыкании на соответствующем канале <code>wb-gpio/A1_IN</code>, состояние меняется, и срабатывает правило.
Для управления через веб-интерфейс создано виртуальное устройство, отображаемое на вкладке '''Устройства'''.
Первоначальные состояния устройств сохраняются в [https://github.com/wirenboard/wb-rules#%D0%BF%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%BD%D0%BE%D0%B5-%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%BB%D0%B8%D1%89%D0%B5 постоянном хранилище]. Переменные в постоянном хранилище записываются на флеш-память, что обеспечивает доступ к ним после перезагрузки контроллера.
<syntaxhighlight lang="ecmascript">
defineVirtualDevice("power_off", {
    title: "Мастер-выключатель",
    cells: {
        power_off: {
            type: "pushbutton"
        },
    }
});
var ps = new PersistentStorage("power-storage", { global: true });
var lights = ["wb-mdm3_50/K1", "wb-mdm3_50/K2", "wb-mdm3_50/K3"];
var isPowerOff = true;
defineRule({
    whenChanged: ["wb-gpio/A1_IN", "power_off/power_off"],
    then: function (newValue, devName, cellName) {
        if (isPowerOff) {
            lights.forEach(function (light) {
                ps[light] = dev[light];
                dev[light] = false;
            });
        } else {
            lights.forEach(function (light) {
                dev[light] = ps[light];
            });
        }
        isPowerOff = !isPowerOff;
    }
});
});
</syntaxhighlight>
</syntaxhighlight>
Строка 1623: Строка 1706:




==Чтение и запись регистров Modbus-устройств==
==Работа с последовательным портом через RPC==
[[File:mqtt-rpc.png|300px|thumb|right|Работа с последовательным портом через RPC]]
Если устройство на шине работает по протоколу, который не поддерживается драйвером [[Wb-mqtt-serial_driver |wb-mqtt-serial]] можно формировать запросы вручную и отправлять их драйверу через [https://github.com/wirenboard/mqtt-rpc RPC-MQTT].


С помощью правил wb-rules можно отправлять запросы Modbus-устройствам, используя драйвер [[Wb-mqtt-serial_driver |wb-mqtt-serial]]. Это может пригодится, когда устройство на шине работает не по стандартному протоколу и не поддерживается драйвером.
RPC-MQTT создает MQTT-топик для отправки запросов, и топик для чтения ответов от драйвера. Поэтому для его использования достаточно отправить запрос в нужный топик функцией <code>publish()</code> и прочитать ответ функцией <code>trackMqtt()</code>. Как узнать адреса топиков описано в [https://github.com/wirenboard/mqtt-rpc документации].


Для взаимодействия wb-rules и драйвера wb-mqtt-serial используется сервис [https://github.com/wirenboard/mqtt-rpc RPC-MQTT].  
В примере написан скрипт на wb-rules для отправки Modbus-запроса устройству Wiren Board на шине RS-485.  


Сервис создает MQTT-топик для отправки запросов, и топик для чтения ответов от драйвера. Поэтому для его использования достаточно отправить запрос в нужный топик функцией <code>publish()</code> и прочитать ответ функцией <code>trackMqtt()</code>. Как узнать адреса топиков описано в [https://github.com/wirenboard/mqtt-rpc документации].
Переменная <code>message</code> содержит Modbus-запрос, сформированный в соответствии со стандартом [[Modbus |Modbus RTU]].  


В примере реализовано чтение Modbus-регистра устройства на шине RS-485.
Переменная <code>pathRPC</code> — это адрес MQTT-топика, в который отправляются запросы для драйвера wb-mqtt-serial. Для каждого сервиса используется свой топик, и узнать его адрес можно из документации на RPC-MQTT.


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Строка 1668: Строка 1753:
name: /rpc/v1/wb-mqtt-serial/port/Load/testRPC/reply,  
name: /rpc/v1/wb-mqtt-serial/port/Load/testRPC/reply,  
value: {"error":null,"id":1,"result":{"response":"0e030400002569df"}}
value: {"error":null,"id":1,"result":{"response":"0e030400002569df"}}
</syntaxhighlight>
== Получение SMS ==
В примере с периодом в 1 секунду выводится в лог вся информация о последнем сообщении. Полученные SMS будут в capturedOutput. Пример из [https://support.wirenboard.com/t/wb7-modem-rabota-s-sms-soobshheniyami/18159 темы на портале].
<syntaxhighlight lang="bash">
var period = 1000;
setInterval(function() {
    runShellCommand("mmcli --modem wbc --messaging-list-sms --output-keyvalue | grep length | cut -f2 -d':'", {
        captureOutput: true,
        exitCallback: function(exitCode, capturedOutput) {
            if (exitCode === 0) {
                runShellCommand("mmcli --modem wbc --sms " + (parseInt(capturedOutput) - 1).toString(), {
                    captureOutput: true,
                    exitCallback: function(exitCode, capturedOutput) {
                        if (exitCode === 0) {
                            log(capturedOutput);
                            return;
                        }
                    }
                });
                return;
            }
        }
    });
}, period);
</syntaxhighlight>
</syntaxhighlight>