wb_editors
38
правок
(Новая страница: «This simple rule monitors the control and sets the other control in the same state.») |
Sikmir (обсуждение | вклад) |
||
(не показаны 92 промежуточные версии 2 участников) | |||
Строка 3: | Строка 3: | ||
You can write rules for the controller, for example: "If the sensor temperature is less than 18°C, turn on the heater." Rules are created via [[Веб-интерфейс Wiren Board/en|web interface]] and written in a simple language similar to Javascript. | You can write rules for the controller, for example: "If the sensor temperature is less than 18°C, turn on the heater." Rules are created via [[Веб-интерфейс Wiren Board/en|web interface]] and written in a simple language similar to Javascript. | ||
The complete description of the rules engine: https://github.com/ | The complete description of the rules engine: https://github.com/wirenboard/wb-rules | ||
Строка 15: | Строка 15: | ||
Notes: | Notes: | ||
#The rules files are stored on the controller as plain text files in the <code>/etc/wb-rules/</code> folder, so they [[Просмотр файлов контроллера с компьютера/en|can be edited and downloaded]] directly from your computer. | #The rules files are stored on the controller as plain text files in the <code>/etc/wb-rules/</code> folder, so they [[Просмотр файлов контроллера с компьютера/en|can be edited and downloaded]] directly from your computer. | ||
#The rules are executed by the ''wb-rules'' service, see the service's [https://github.com/ | #The rules are executed by the ''wb-rules'' service, see the service's [https://github.com/wirenboard/wb-rules documentation on Github]. | ||
== Writing the first rule== | == Writing the first rule == | ||
[[File:Web-scripts-rule1.png|400px|thumb|The rule for the heater control, written via the web interface]] | [[File:Web-scripts-rule1.png|400px|thumb|The rule for the heater control, written via the web interface]] | ||
Строка 86: | Строка 86: | ||
#* on the same page below; | #* on the same page below; | ||
#* in [http://forums.contactless.ru/t/dvizhok-pravil-primery-koda/483 a special topic on our forum(ru)]. | #* in [http://forums.contactless.ru/t/dvizhok-pravil-primery-koda/483 a special topic on our forum(ru)]. | ||
#[https://github.com/ | #[https://github.com/wirenboard/wb-rules Full description of the rules engine]. | ||
Строка 97: | Строка 97: | ||
This simple rule monitors the control and sets the other control in the same state. | This simple rule monitors the control and sets the other control in the same state. | ||
For example, a rule can include a siren and a lamp if the motion sensor has noticed movement. | |||
In the example, the motion sensor is connected to the input "dry contact", control type "switch". The siren is connected to the built-in relay Wiren Board, and the lamp - through the relay unit by Modbus. When the input type "dry contact" (output motion sensor) is closed, the lamp and the relay get "1", when off - "0". | |||
The rule is triggered every time the control value "D1_IN" of the device "wb-gpio" is changed. The new value of this control is passed to the rule code as a newValue variable. | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 118: | Строка 118: | ||
The same, but with a virtual device as a source of events. Example of use: scenario button that turns on/off the siren and light bulb. | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 145: | Строка 145: | ||
=== | === Motion detection with timeout === | ||
The motion detector with the "dry contact" output type is connected to the D2 input, which closes the D2 and GND when motion is detected. At the same time, the status "1" appears on the "wb-gpio/D2_IN" channel. | |||
The rule turns on the light when motion is detected and turns off the light 30 seconds after the motion sensor signal disappears. | |||
Lighting is connected via built-in relay, wb-gpio/Relay_1 channel. | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 181: | Строка 180: | ||
=== | === Creating similar rules === | ||
If you need several such motion detectors, you can wrap the creation of rules and variables into a function to avoid copying the code: | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 213: | Строка 212: | ||
=== | === Activate a rule only at a specific time === | ||
The rule is as in the previous section, but runs only from 9:30 to 17:10 UTC. | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 258: | Строка 257: | ||
=== | === Rolling shutters === | ||
One relay includes the engine, raising the curtains, the second relay - includes the engine, lowering the curtains. The rule ensures that both relays are not switched on at the same time. | |||
In addition, the rule turns off the engines after a specified time after switching on. | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 338: | Строка 336: | ||
An older version of the same script demonstrates the use of aliases: | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 384: | Строка 382: | ||
=== | === System rules === | ||
Some rules come with the default rule system in the wb-rules-system package. | |||
Full list of rules is [https://github.com/wirenboard/wb-rules-system/tree/master/rules in the repository.]. | |||
Some examples: | |||
==== | ==== The rule for the buzzer==== | ||
[https://github.com/ | The [https://github.com/wirenboard/wb-rules-system/blob/master/rules/buzzer.js rule] creates a virtual buzzer device with sliders to adjust the volume and frequency, as well as a button to turn on the sound. | ||
Строка 469: | Строка 467: | ||
==== | ==== Power status rule ==== | ||
[https://github.com/ | [https://github.com/wirenboard/wb-rules-system/blob/master/rules/power_status.js The rule] creates a virtual device that reports the current power status. Two ADC channels are used as input data: battery voltage measurement and input voltage measurement. | ||
The following logic is implemented: | |||
1. | 1. If the input voltage is less than the voltage on the battery, then the Board is powered by the battery. In this case, 0V is also displayed as the input voltage. | ||
2. | 2. If the input voltage is greater than the battery voltage, the Board is powered by an external power supply. The measurement from the Vin channel is displayed as the input voltage. | ||
To illustrate, the rules use two different ways of triggering: by changing the value of the control (rule _system_track_vin) and by changing the value of the expression (the other two). | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 539: | Строка 537: | ||
=== | === Sending commands via RS-485 === | ||
For example, send a command to the device on the port /dev/ttys0 (corresponds to the hardware port RS-485-ISO on the [[Special:MyLanguage/Wiren Board 4|Wiren Board 4]]). To do this, we will use the rules engine and the ability to execute arbitrary shell commands. See [https://github.com/wirenboard/wb-rules#%D0%94%D1%80%D1%83%D0%B3%D0%B8%D0%B5-%D0%BF%D1%80%D0%B5%D0%B4%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D1%91%D0%BD%D0%BD%D1%8B%D0%B5-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8-%D0%B8-%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%8B%D0%B5 documentation] for details. | |||
Create a virtual device with switch type control via rules engine. | |||
When you turn on the switch a command will be sent: (Set Brightness ch. 00=0xff) for Uniel UCH-M141: | |||
<pre> | <pre> | ||
FF FF 0A 01 FF 00 00 0A | FF FF 0A 01 FF 00 00 0A | ||
Строка 552: | Строка 549: | ||
When you turn off the switch a command will be sent: (set channel brightness 00=0x00) for Uniel UCH-M141: | |||
<pre> | <pre> | ||
FF FF 0A 01 00 00 00 0B | FF FF 0A 01 00 00 00 0B | ||
Строка 561: | Строка 558: | ||
1. | 1. Port setting | ||
To configure the / dev/ttyNSC0 port to 9600 speed, run the following command | |||
<pre> | <pre> | ||
Строка 569: | Строка 566: | ||
</pre> | </pre> | ||
2. | 2. Sending a command | ||
You can send data by the following shell command: | |||
<pre> | <pre> | ||
/usr/bin/printf '\xFF\xFF\x0A\x01\xD1\x06\x00\xE2' >/dev/ttyNSC0 | /usr/bin/printf '\xFF\xFF\x0A\x01\xD1\x06\x00\xE2' >/dev/ttyNSC0 | ||
</pre> | </pre> | ||
where "\xFF\xFF\x0A\x01\xD1\x06\x00\xE2" - is the entry of a "FF FF 0A 01 D1 06 00 E2" command. | |||
3. | 3. Create the new rules file <code>/etc/wb-rules/rs485_cmd.js</code> in the rules engine | ||
The file can be edited with vim, nano, or mcedit in an ssh session on the device, or it can be downloaded with SCP. | |||
<pre> | <pre> | ||
Строка 588: | Строка 585: | ||
4. | 4. Describe the virtual device in the file | ||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 603: | Строка 600: | ||
5. | 5. Restart wb-rules and check the operation | ||
<pre> | <pre> | ||
Строка 610: | Строка 607: | ||
</pre> | </pre> | ||
There should be no error messages in the log (exit via control-c) | |||
A new device "Send custom command to RS-485 port"should appear in the Devices section of the web interface. | |||
6. | 6. Add a function to configure the port. | ||
Строка 627: | Строка 624: | ||
7. | 7. Let's describe the rules for switching on and off the switch | ||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 651: | Строка 648: | ||
Note the double shielding. | |||
8. Putting it all together | |||
Full contents of the rules file: | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
Строка 694: | Строка 691: | ||
}); | }); | ||
setTimeout(setup_port, 1000); // | setTimeout(setup_port, 1000); // set setup_port() running 1 second after starting. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Строка 700: | Строка 697: | ||
=== | === User fields in the interface === | ||
To enable the user to enter exact parameter values (setpoints) from the interface, you can use the [https://wirenboard.com/wiki/index.php/%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%B8%D1%80%D1%83%D0%B5%D0%BC%D1%8B%D1%85_%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%B8%D1%85_%D0%BF%D0%BE%D0%BB%D0%B5%D0%B9_%D0%B2_%D0%B2%D0%B5%D0%B1-%D0%B8%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81%D0%B5 instruction]. | |||
More detailed and with example - in the topic on the technical support [https://support.wirenboard.com/t/kak-na-wb5-wb6-sozdat-pole-dlya-vvoda-ustavok-i-peredat-znachenie-v-pravila/2180 forum]. | |||
=== | === Complex scheduled rules === | ||
Object - grocery store. Various store systems are controlled by feedback from temperature sensors and taking into account the schedule of the store. | |||
Not cron-rules are used for schedules, but the libschedule. The libschedule enables and disables rules, which, unlike cron rules, are executed continuously when enabled. | |||
For example, we want the lighting to be on from 10 to 17h. The libschedule will follow the "turn on the lights" rule once a minute from 10 am to 17 PM. | |||
This means that even if the controller works intermittently and missed the transition time between schedules (10 am), the controller will still turn on the lighting as soon as possible. | |||
Строка 724: | Строка 721: | ||
global.__proto__.Schedules = {}; | global.__proto__.Schedules = {}; | ||
(function(Schedules) { // | (function(Schedules) { // closing | ||
function todayAt(now, hours, minutes) { | function todayAt(now, hours, minutes) { | ||
Строка 864: | Строка 861: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
An example of a rule using Schedules: | |||
<syntaxhighlight lang="ecmascript"> | <syntaxhighlight lang="ecmascript"> | ||
(function() { // | (function() { // closing | ||
defineAlias("countersTemperature", "wb-msw2_30/Temperature"); | defineAlias("countersTemperature", "wb-msw2_30/Temperature"); | ||
Строка 918: | Строка 915: | ||
Schedules.initSchedules(); | Schedules.initSchedules(); | ||
// | // signboard and facade illumination | ||
defineRule("signboardOnOff", { | defineRule("signboardOnOff", { | ||
when: function() { | when: function() { | ||
Строка 934: | Строка 931: | ||
// | // sales area illumination | ||
defineRule("lightingFrontshopOnOff", { | defineRule("lightingFrontshopOnOff", { | ||
when: function() { | when: function() { | ||
Строка 941: | Строка 938: | ||
then: function (newValue, devName, cellName) { | then: function (newValue, devName, cellName) { | ||
log("lightingFrontshopOnOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("lightingFrontshopOnOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
dev["wb-gpio/EXT1_R3A1"] = ! dev._schedules.frontshop_lighting; // | dev["wb-gpio/EXT1_R3A1"] = ! dev._schedules.frontshop_lighting; //inverted contactor | ||
} | } | ||
}); | }); | ||
// | // backstoreroom ventilation | ||
defineRule("ventBackstoreOnOff", { | defineRule("ventBackstoreOnOff", { | ||
when: function() { | when: function() { | ||
Строка 954: | Строка 951: | ||
log("ventBackstoreOnOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("ventBackstoreOnOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
var on = dev._schedules.ext_working_hours_15m; | var on = dev._schedules.ext_working_hours_15m; | ||
dev["wb-mr6c_81/K1"] = ! on; // | dev["wb-mr6c_81/K1"] = ! on; //inverted contactor | ||
dev["wb-mr6c_81/K5"] = ! on; // | dev["wb-mr6c_81/K5"] = ! on; //inverted contactor | ||
} | } | ||
}); | }); | ||
// | // Freezer showcase illumination | ||
defineRule("lightingCoolingshelfsOnOff", { | defineRule("lightingCoolingshelfsOnOff", { | ||
when: function() { | when: function() { | ||
Строка 968: | Строка 965: | ||
var on = dev._schedules.working_hours_15m; | var on = dev._schedules.working_hours_15m; | ||
// | // | ||
the lighting in the freezer showcases via the normally-closed relays (inverted) | |||
dev["wb-mrm2-old_60/Relay 1"] = !on; | dev["wb-mrm2-old_60/Relay 1"] = !on; | ||
dev["wb-mrm2-old_61/Relay 1"] = !on; | dev["wb-mrm2-old_61/Relay 1"] = !on; | ||
Строка 981: | Строка 979: | ||
// | //Display fridges | ||
defineRule("powerBrandFridgesOnOff", { | defineRule("powerBrandFridgesOnOff", { | ||
when: function() { | when: function() { | ||
Строка 990: | Строка 988: | ||
var on = dev._schedules.working_hours; | var on = dev._schedules.working_hours; | ||
dev["wb-gpio/EXT1_R3A5"] = !on; // | dev["wb-gpio/EXT1_R3A5"] = !on; // inverted | ||
} | } | ||
}); | }); | ||
// ========= | // ========= Boilers and supply ventilation =========== | ||
// | // feedback by the temperature of the vegetable zone | ||
// | // position controller works daily | ||
defineRule("heatersDayOff", { | defineRule("heatersDayOff", { | ||
when: function() { | when: function() { | ||
Строка 1005: | Строка 1003: | ||
then: function (newValue, devName, cellName) { | then: function (newValue, devName, cellName) { | ||
log("heatersDayOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("heatersDayOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
heater1EnableInverted = !false; // | heater1EnableInverted = !false; // inverted | ||
} | } | ||
}); | }); | ||
Строка 1015: | Строка 1013: | ||
then: function (newValue, devName, cellName) { | then: function (newValue, devName, cellName) { | ||
log("heatersDayOn newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("heatersDayOn newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
heater1EnableInverted = !true; // | heater1EnableInverted = !true; // inverted | ||
} | } | ||
}); | }); | ||
// | // position controller works at night | ||
defineRule("heatersNightOff", { | defineRule("heatersNightOff", { | ||
when: function() { | when: function() { | ||
Строка 1026: | Строка 1024: | ||
then: function (newValue, devName, cellName) { | then: function (newValue, devName, cellName) { | ||
log("heatersNightOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("heatersNightOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
heater1EnableInverted = !false; // | heater1EnableInverted = !false; // inverted | ||
} | } | ||
}); | }); | ||
Строка 1036: | Строка 1034: | ||
then: function (newValue, devName, cellName) { | then: function (newValue, devName, cellName) { | ||
log("heatersNightOn newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("heatersNightOn newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
heater1EnableInverted = !true; // | heater1EnableInverted = !true; // inverted | ||
} | } | ||
}); | }); | ||
// | // supply and exhaust ventilation are forcibly switched off | ||
defineRule("ventFrontshopAlwaysOff", { | defineRule("ventFrontshopAlwaysOff", { | ||
Строка 1052: | Строка 1050: | ||
// ================== | // ================== The cash register area ================= | ||
// | // in the cash area during working hours the temperature is maintained by air conditioning (position controller) | ||
defineRule("countersACOn", { | defineRule("countersACOn", { | ||
Строка 1062: | Строка 1060: | ||
then: function (newValue, devName, cellName) { | then: function (newValue, devName, cellName) { | ||
log("countersACOn newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("countersACOn newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
dev["wb-mir_75/Play from ROM7"] = true; // | dev["wb-mir_75/Play from ROM7"] = true; // air conditioning cash area for heating | ||
} | } | ||
}); | }); | ||
// | // after working hours, the air conditioning is off | ||
defineRule("countersACOff", { | defineRule("countersACOff", { | ||
when: function() { | when: function() { | ||
Строка 1073: | Строка 1071: | ||
then: function (newValue, devName, cellName) { | then: function (newValue, devName, cellName) { | ||
log("countersACOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("countersACOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
dev["wb-mir_75/Play from ROM2"] = true; // | dev["wb-mir_75/Play from ROM2"] = true; // shut down air conditioning cash area | ||
} | } | ||
}); | }); | ||
// =============== | // =============== Vegetable zone ============== | ||
// | // Cooling vegetables air-conditioned only when the air temperature is above 18.5 C | ||
defineRule("acVegOn", { | defineRule("acVegOn", { | ||
Строка 1086: | Строка 1084: | ||
then: function (newValue, devName, cellName) { | then: function (newValue, devName, cellName) { | ||
log("acVegOn newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("acVegOn newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
dev["wb-mir_76/Play from ROM3"] = true; // | dev["wb-mir_76/Play from ROM3"] = true; // Cooling +18 | ||
} | } | ||
}); | }); | ||
Строка 1096: | Строка 1094: | ||
then: function (newValue, devName, cellName) { | then: function (newValue, devName, cellName) { | ||
log("acVegOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | log("acVegOff newValue={}, devName={}, cellName={}", newValue, devName, cellName); | ||
dev["wb-mir_76/Play from ROM2"] = true; // | dev["wb-mir_76/Play from ROM2"] = true; // shutdown | ||
} | } | ||
}); | }); | ||
Строка 1104: | Строка 1102: | ||
== | == A full description of the capabilities of the rules engine == | ||
The most complete description of the rules engine: https://github.com/wirenboard/wb-rules/blob/master/README.md | |||
== | == What's new in the latest versions == | ||
* [[Special:MyLanguage/Движок_правил_wb-rules_1.7| | * [[Special:MyLanguage/Движок_правил_wb-rules_1.7/en|wb-rules 1.7 rules engine]] | ||
== | == under development == | ||
A description of the features of future versions of the rules engine can be found here: | |||
* [[Special:MyLanguage/Движок_правил_wb-rules_2.0| | * [[Special:MyLanguage/Движок_правил_wb-rules_2.0/en|Rules engine wb-rules 2.0]] |