Skip to content

Commit

Permalink
Show alarm titles (#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
sikmir committed Apr 3, 2024
1 parent 5678ee6 commit cf4800f
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 86 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ _testmain.go
*.exe
*.test
*.prof
*.log

# Tern port file
.tern-port
Expand Down
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ defineRule("Examle_rule", {
**whenChanged.** При задании `whenChanged` правило срабатывает при любых изменениях значений параметров, указанных в массиве. Каждый параметр задаётся в виде "имя устройства/имя параметра":
```js
// Правило выводит в лог состояние переключателей Devices → Discrete I/O → A1_OUT и Devices → Discrete I/O → A2_OUT
defineRule("test_whenChanged", {
defineRule("test_whenChanged", {
whenChanged: ["wb-gpio/A1_OUT", "wb-gpio/A2_OUT"], // топики, при изменении которых сработает правило
then: function (newValue, devName, cellName) {
log("devName:{}, cellName:{}, newValue:{}", devName, cellName, newValue); // вывод сообщения в лог
Expand All @@ -81,7 +81,7 @@ defineRule("test_whenChanged", {
Если нужно отслеживать один топик, то вместо массива можно просто задать строку "имя устройства/имя параметра":
```js
// Правило выводит в лог состояние переключателя Devices → Discrete I/O → A1_OUT
defineRule("test_whenChanged", {
defineRule("test_whenChanged", {
whenChanged: "wb-gpio/A1_OUT", // топик, при изменении которого сработает правило
then: function (newValue, devName, cellName) {
log("devName:{}, cellName:{}, newValue:{}", devName, cellName, newValue); // вывод сообщения в лог
Expand All @@ -90,9 +90,9 @@ defineRule("test_whenChanged", {
```

В функцию, заданную в значении ключа `then`, передаются в качестве
аргументов текущее значение параметра `newValue`, имя устройства `devName` и имя параметра `cellName`, изменение которого привело к срабатыванию правила.
аргументов текущее значение параметра `newValue`, имя устройства `devName` и имя параметра `cellName`, изменение которого привело к срабатыванию правила.

В случае, если правило сработало из-за изменения функции, фигурирующей в `whenChanged`, в качестве единственного аргумента в `then` передаётся текущее значение этой функции.
В случае, если правило сработало из-за изменения функции, фигурирующей в `whenChanged`, в качестве единственного аргумента в `then` передаётся текущее значение этой функции.

Если срабатывание правила не связано непосредственно
с изменением параметра (например, вызов при инициализации, по таймеру или через `runRule()`), `then` вызывается без аргументов, т.е. значением всех трёх аргументов будет `undefined`.
Expand All @@ -115,7 +115,7 @@ defineRule("test_whenChanged", {
// Правило сработает, когда переключатель Devices → Discrete I/O → A1_OUT будет включён и выключит его
defineRule({
asSoonAs: function() {
return dev["wb-gpio/A1_OUT"]; // правило сработает, когда значение параметра изменится на истинное
return dev["wb-gpio/A1_OUT"]; // правило сработает, когда значение параметра изменится на истинное
},
then: function (newValue, devName, cellName) {
log("Переключатель {} включён! Выключаем…", cellName);
Expand Down Expand Up @@ -159,7 +159,7 @@ defineRule("crontest_hourly", {

### Объект `dev`

Объект 'dev' определяет MQTT-топик в правилах wb-rules.
Объект 'dev' определяет MQTT-топик в правилах wb-rules.

Синтаксис:

Expand Down Expand Up @@ -217,7 +217,7 @@ defineRule("anotherRule", {
```

### Виртуальные устройства
С помощью виртуальных устройств можно создать управляющий элемент
С помощью виртуальных устройств можно создать управляющий элемент
с внутренним набором функций, например, термостат.

Виртуальное устройство задаётся так:
Expand Down Expand Up @@ -369,7 +369,7 @@ defineRule({
if (n >= 10){
clearInterval(test_interval);
}
}, 500);
}, 500);
}
}
});
Expand Down Expand Up @@ -460,15 +460,15 @@ MQTT-значений.
образом: вызывается функция, заданная в `when`. Если функция
обращается хотя бы к одному неполному параметру, правило не
выполняется. Если функция не обращалась к неполным параметрам
и вернула истинное значение, правило выполняется.
и вернула истинное значение, правило выполняется.

В любом
случае все параметры, доступные через `dev`, доступ к которым
осуществлялся во время выполнения функции, фиксируются, и в
дальнейшем при получении значений параметров из MQTT правило
просматривается только тогда, когда topic полученного сообщения
относится к параметру, хотя бы раз опрашивавшемуся в `when`-функции
данного правила.
данного правила.

Аналогичным образом фиксируется доступ
к объекту `timers` - при срабатывании таймеров, запущенных
Expand All @@ -482,7 +482,7 @@ MQTT-значений.
выполняется. Если функция не обращалась к неполным параметрам
и вернула истинное значение, и при этом правило просматривается
первый раз, либо при предыдущем просмотре значение функции
было ложным, правило выполняется.
было ложным, правило выполняется.

В любом случае все параметры,
доступные через `dev`, доступ к которым осуществлялся во время
Expand Down Expand Up @@ -713,7 +713,7 @@ defineRule("onChange", {

Для проверки контрола на существование можно воспользоваться функцией `isControlExists(<id контрола>)`. Так как при попытке установить
значения контролов не виртуальных (внешних) девайсов возникает исключение — для проверки на принадлежность девайса можно использовать
метод `isVirtual()`.
метод `isVirtual()`.

Для удобства выполнения операция над всеми контролами, присутствующими на девайсе можно использовать
метод получения массива контролов `controlsList()` и, например, итерировать его так:
Expand All @@ -737,12 +737,12 @@ getDevice("deviceID").controlsList().forEach(function(ctrl) {

Контролам можно устанавливать значения мета-полей при помощи сеттеров.
Например, установить `description` можно при помощи метода `setDescription(string)`, `units``setUnits(string)` и т.д.
Аналогично можно и получать значения этих полей геттерами, например, для `description``getDescription()`
Аналогично можно и получать значения этих полей геттерами, например, для `description``getDescription()`

Полный список методов объекта контрола смотрите ниже.

Setters:
* `setTitle(string)` или `setTitle({ "en": string, "ru": string })`
* `setTitle(string)` или `setTitle({ en: string, ru: string })`
* `setEnumTitles(object)` (параметр вида `{'val1': {'en': 'Title1', 'ru': 'Заголовок1'}, ...}`)
* `setDescription(string)`
* `setType(string)`
Expand Down Expand Up @@ -1082,7 +1082,7 @@ var myModule = require("path/to/myModule");

## Сервис оповещений

С помощью сервиса оповещений можно отправлять сообщение на электронную почту или через SMS.
С помощью сервиса оповещений можно отправлять сообщение на электронную почту или через SMS.

`Notify.sendEmail(to, subject, text)` отправляет почту указанному
адресату (`to`), с указанной темой (`subject`) и содержимым (`text`).
Expand Down Expand Up @@ -1149,7 +1149,7 @@ var myModule = require("path/to/myModule");
"to": "+78122128506",

// Команда для отправки SMS. Поле можно оставить пустым, чтобы использовать
// gammu. В команде нужно указать как минимум один плейсхолдер {} - для номера. Тогда
// gammu. В команде нужно указать как минимум один плейсхолдер {} - для номера. Тогда
// текст будет отправлен в stdin. Если указать 2 плейсхолдера - то в первый запишется
// номер, во второй - текст.
// Примеры:
Expand Down
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
wb-rules (2.20.2) stable; urgency=medium

* Show alarm titles

-- Nikolay Korotkiy <nikolay.korotkiy@wirenboard.com> Thu, 28 Mar 2024 17:33:00 +0400

wb-rules (2.20.1) stable; urgency=medium

* Allow specifying enum titles in virtual device definition
Expand Down
14 changes: 8 additions & 6 deletions scripts/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -581,9 +581,10 @@ var Alarms = (function () {
return d[ref.control];
}

function setAlarmActiveCell(active) {
function setAlarmActiveCell(active, title) {
active = !!active;
if (dev[alarmDeviceName][cellName] !== active) dev[alarmDeviceName][cellName] = active;
getDevice(alarmDeviceName).getControl(cellName).setTitle(title);
}

var wasActive = false,
Expand All @@ -607,7 +608,7 @@ var Alarms = (function () {
}

function activateAlarm() {
setAlarmActiveCell(true);
setAlarmActiveCell(true, maybeFormat(alarmMessage, cellValue()));

remainingCount = maxCount;

Expand All @@ -620,7 +621,7 @@ var Alarms = (function () {
}

function deactivateAlarm() {
setAlarmActiveCell(false);
setAlarmActiveCell(false, maybeFormat(noAlarmMessage, cellValue()));
stopRepeating();
notify(maybeFormat(noAlarmMessage, cellValue()));
wasActive = false;
Expand All @@ -646,7 +647,7 @@ var Alarms = (function () {

if (!wasActive) {
if (alarmSrc.alarmDelayMs > 0)
activateTimerId = setTimeout(function() {
activateTimerId = setTimeout(function () {
activateTimerId = null;
activateAlarm();
}, alarmSrc.alarmDelayMs);
Expand Down Expand Up @@ -674,15 +675,15 @@ var Alarms = (function () {
// alarms remaining from before wb-rules startup /
// loading of this rule file.
if (!wasTriggered) {
setAlarmActiveCell(false);
setAlarmActiveCell(false, maybeFormat(noAlarmMessage, cellValue()));
return;
}

wasTriggered = false;

if (wasActive) {
if (alarmSrc.noAlarmDelayMs > 0) {
deactivateTimerId = setTimeout(function() {
deactivateTimerId = setTimeout(function () {
deactivateTimerId = null;
deactivateAlarm();
}, alarmSrc.noAlarmDelayMs);
Expand Down Expand Up @@ -723,6 +724,7 @@ var Alarms = (function () {
var deviceDef = {
cells: {
log: {
title: { en: 'Log', ru: 'Лог' },
type: 'text',
value: '',
readonly: true,
Expand Down
18 changes: 0 additions & 18 deletions wbrules/alarms.conf
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,6 @@
"alarmMessage": "Important device is off",
"noAlarmMessage": "Important device is back on",
"interval": 200
},
{
// not repeated
"name": "unnecessaryDeviceIsOn",
"cell": "somedev/unnecessaryDevicePower",
"expectedValue": 0,
"alarmMessage": "Unnecessary device is on"
},
{
// notification repeated every 10s while active, but no more than 10 times
"name": "temperatureOutOfBounds",
"cell": "somedev/devTemp",
"minValue": 10, // **mintemp** (comment used by test)
"maxValue": 15, // **maxtemp** (comment used by test)
"alarmMessage": "Temperature out of bounds, value = {{dev.somedev.devTemp}}",
"noAlarmMessage": "Temperature is within bounds again, value = {}",
"interval": 10,
"maxCount": 5
}
]
}
29 changes: 29 additions & 0 deletions wbrules/alarms1.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"deviceName": "sampleAlarms",
"deviceTitle": "Sample Alarms",
"recipients": [
{
"type": "email",
"to": "someone@example.com",
"subject": "alarm!"
},
{
"type": "email",
"to": "anotherone@example.com",
"subject": "Alarm: {}"
},
{
"type": "sms",
"to": "+78122128506"
}
],
"alarms": [
{
// not repeated
"name": "unnecessaryDeviceIsOn",
"cell": "somedev/unnecessaryDevicePower",
"expectedValue": 0,
"alarmMessage": "Unnecessary device is on"
}
]
}
33 changes: 33 additions & 0 deletions wbrules/alarms2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"deviceName": "sampleAlarms",
"deviceTitle": "Sample Alarms",
"recipients": [
{
"type": "email",
"to": "someone@example.com",
"subject": "alarm!"
},
{
"type": "email",
"to": "anotherone@example.com",
"subject": "Alarm: {}"
},
{
"type": "sms",
"to": "+78122128506"
}
],
"alarms": [
{
// notification repeated every 10s while active, but no more than 10 times
"name": "temperatureOutOfBounds",
"cell": "somedev/devTemp",
"minValue": 10, // **mintemp** (comment used by test)
"maxValue": 15, // **maxtemp** (comment used by test)
"alarmMessage": "Temperature out of bounds, value = {{dev.somedev.devTemp}}",
"noAlarmMessage": "Temperature is within bounds again, value = {}",
"interval": 10,
"maxCount": 5
}
]
}
Loading

0 comments on commit cf4800f

Please sign in to comment.