You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|[Blockly]({{base}}/configuration/blockly/)| See the previous page | Non-developers |
22
-
|[Rules DSL]({{base}}/configuration/rules-dsl.html)| A programming language developed specifically for openHAB based on the Xtend. | Long time openHAB users |
23
-
|[ECMAScript 5.1]({{base}}/configuration/jsr223.html)| An older version of JavaScript built into Java Virtual Machine 14 and before. It's the language Blockly "compiles" into which can be a powerful learning tool (i.e. build a rule in Blockly and examine the code it generates to see how it works). | Not recommended for use, will go away at sometime soon (Blockly will be updated at that time to use an alternative). |
|[Blockly]({{base}}/configuration/blockly/)| See the previous page | Non-developers |
22
+
|[Rules DSL]({{base}}/configuration/rules-dsl.html)| A programming language developed specifically for openHAB based on [Xtend](https://eclipse.dev/Xtext/xtend/). | Long time openHAB users |
24
23
25
24
In addition to these default choices, one can install a number of different languages as an Automation add-on.
26
-
Such diverse languages as Python, Ruby, Groovy, Java, and more are available with more to come.
25
+
Such diverse languages as [JavaScript](/addons/automation/jsscripting/), [Ruby](/addons/automation/jrubyscripting), [Python](/addons/automation/jythonscripting/), [Groovy](/addons/automation/groovyscripting/), Java, and more are available with more to come.
27
26
See the add-on docs for the reference guide and specific information for how to use each individual add-on.
28
27
Take note, not all automation add-ons support writing rules in the UI.
29
28
30
-
For the rest of this tutorial we will use the [JavaScript Scripting add-on](/addons/automation/jsscripting/) which implements ECMAScript 2021 for Script Actions and Script Conditions in UI rules.
29
+
For the rest of this tutorial we will show how to use the [JavaScript Scripting add-on](/addons/automation/jsscripting/) which implements ECMAScript 2021, and [Ruby](/addons/automation/jrubyscripting) for Script Actions and Script Conditions in UI rules.
31
30
See the add-on's reference for how to write rules in text files which is outside the scope of this tutorial.
32
31
33
32
## Installation
@@ -52,8 +51,27 @@ These libraries come in various forms and are installed in different ways but th
52
51
- abstract some of the sometimes verbose series of steps requires to do something (e.g. access an Item's metadata) into a single function call.
53
52
54
53
See the automation add-on's reference for how to access and install the Helper Library for your language of choice.
54
+
55
+
:::: tabs
56
+
57
+
::: tab JS
58
+
55
59
In the case of JavaScript Scripting, the Helper Library comes with the add-on (nothing to install separately) and it is automatically imported into your rules for you (advanced users can turn off that auto import in MainUI Settings -> JS Scripting).
56
60
To get the latest version of the Helper Library instead of waiting for the next release of OH, it can be installed using `npm`.
61
+
62
+
:::
63
+
64
+
::: tab JRuby
65
+
66
+
The Ruby scripting is implemented using JRuby Scripting add-on.
67
+
It will install its helper library by default, and it is automatically imported into your rules.
68
+
This can be configured or disabled in Main UI Settings -> JRuby Scripting.
69
+
Additional Ruby Gems can be installed by specifying them in the `gems` configuration.
70
+
71
+
:::
72
+
73
+
::::
74
+
57
75
Again, see the add-on's reference for details.
58
76
59
77
## Creating a Rule
@@ -76,26 +94,51 @@ We will use the same trigger from the Blockly tutorial.
76
94
77
95
### Then: Actions
78
96
79
-
Just like in Blockly, we will create a new Action but instead of choosing Blockly, we will choose ECMAScript 2021.
97
+
Just like in Blockly, we will create a new Action but instead of choosing Blockly, we will choose `ECMAScript` or `Ruby`.
This will open a blank text field where you can start typing your code.
84
102
This text field provides text highlighting and some code completion which helps with coding.
85
103
104
+
As with the Blockly example, we want to start the rule using a log statement we can see in openhab.log when the rule runs.
105
+
106
+
:::: tabs
107
+
108
+
::: tab JS
109
+
86
110
As previously mentioned, the Helper Library for this language comes with the add-on and is imported by default, so see the [JavaScript Scripting add-on's reference](/addons/automation/jsscripting/) for the full guide on how to do anything you might want to do.
87
111
For help with general JavaScript coding, there are tons of tutorials and reference documents on the web a search away.
88
112
89
-
As with the Blockly example, we want to start the rule using a log statement we can see in openhab.log when the rule runs.
90
113
One can either use the [log actions](/addons/automation/jsscripting/#log) but most will find it easiest to use the more JavaScript native [`console`](/addons/automation/jsscripting/#console).
91
114
92
115
```javascript
93
116
console.info('Motion was detected');
94
117
```
95
118
119
+
:::
120
+
121
+
::: tab JRuby
122
+
123
+
If you are new to Ruby, check out [Ruby Basics](https://openhab.github.io/openhab-jruby/main/file.ruby-basics.html) for a quick overview of the language.
124
+
The Ruby language and the [JRuby Helper Library](https://openhab.github.io/openhab-jruby/) offers a streamlined syntax for writing file-based and UI-based rules, making it easier and more intuitive than RulesDSL, while delivering the full features of the Ruby language.
125
+
126
+
```ruby
127
+
logger.info "Motion was detected"
128
+
```
129
+
130
+
:::
131
+
132
+
::::
133
+
96
134
Save and test the rule by running it manually and verify you see this statement in the logs.
97
135
98
-
Next we want to `sendCommand` to the light to turn it on.
136
+
Next we want to send a command to the light to turn it on.
137
+
138
+
:::: tabs
139
+
140
+
::: tab JS
141
+
99
142
Reading the docs we see that access to the Item registry is provided through [`Items`](/addons/automation/jsscripting/#items) where we can get access to a JavaScript Object that represents the Item.
100
143
This Object has a `sendCommand()` function that takes the command.
101
144
@@ -104,9 +147,36 @@ console.info('Motion was detected');
In JRuby, openHAB Items are represented directly by their names.
155
+
You can also access them through the [items](https://openhab.github.io/openhab-jruby/main/OpenHAB/DSL.html#items-class_method) registry so you can find them using a string.
156
+
The Item object has a generic [#command](https://openhab.github.io/openhab-jruby/main/OpenHAB/Core/Items/GenericItem.html#command-instance_method) method and also command methods specific for each item type in openHAB.
157
+
158
+
```ruby
159
+
logger.info "Motion was detected"
160
+
FrontPorchLight.on # this sends the ON command to the Item
161
+
162
+
# The following lines do the same thing
163
+
# FrontPorchLight.command ON
164
+
# items["FrontPorchLight"].on
165
+
# items["FrontPorchLight"].comand ON
166
+
```
167
+
168
+
:::
169
+
170
+
::::
171
+
107
172
Save and test and verify you see the log statement and the Item receive an ON command.
108
173
109
174
Now we want to create a Timer to go off in 30 minutes.
175
+
176
+
:::: tabs
177
+
178
+
::: tab JS
179
+
110
180
We find the Timer creation documented under [ScriptExecution](/addons/automation/jsscripting/#scriptexecution-actions).
111
181
A Timer will execute a block of code passed to it as the second argument at the time specified by the first argument.
112
182
@@ -137,10 +207,37 @@ var lightsOut = function() {
Timers are created by calling the [after](https://openhab.github.io/openhab-jruby/main/OpenHAB/DSL.html#after-class_method) method.
215
+
It accepts a [Duration](https://openhab.github.io/openhab-jruby/main/OpenHAB/CoreExt/Java/Duration.html), a Ruby [Time](https://docs.ruby-lang.org/en/master/Time.htmll), or a java [ZonedDateTime](https://openhab.github.io/openhab-jruby/main/OpenHAB/CoreExt/Java/ZonedDateTime.html) object to specify when the timer should execute.
216
+
Most of the time, a Duration is used, and the helper library offers a [convenient syntax](https://openhab.github.io/openhab-jruby/main/index.html#durations), e.g. `30.minutes`, to create a Duration object.
217
+
218
+
```ruby
219
+
logger.info "Motion was detected"
220
+
FrontPorchLight.on
221
+
222
+
after 30.minutes do
223
+
logger.info "No more motion, turning off the light"
224
+
FrontPorchLight.off
225
+
end
226
+
```
227
+
228
+
:::
229
+
230
+
::::
231
+
140
232
Save and test that you see the log statement and the Item receive the `ON` command and 30 minutes later the second log statement and the `OFF` command.
141
233
(hint, change the time passed to the timer to something smaller to make testing easier then change it back once things are working).
142
234
143
235
Now all we are lacking is the ability to reschedule that timer if motion is seen again in the 30 minute period.
236
+
237
+
:::: tabs
238
+
239
+
::: tab JS
240
+
144
241
Looking back at the docs we find the [`cache`](/addons/automation/jsscripting/#cache).
145
242
This is a map of key/value pairs that exists outside of the rule.
146
243
Given that position it is able to share data between different rules or between runs of the same rule.
@@ -171,18 +268,51 @@ Also notice a line was added to `lightsOut` to delete the entry in the `cache` w
171
268
That will cause the rule to create a new timer the next time the rule runs.
172
269
It could be coded to reuse the Timer instead which is an exercise for the reader.
173
270
271
+
:::
272
+
273
+
::: tab JRuby
274
+
275
+
In JRuby, an easy way to reschedule the same timer is done by providing a unique `id` to the timer.
276
+
This is called a [reentrant timer](https://openhab.github.io/openhab-jruby/main/OpenHAB/DSL.html#reentrant-timers).
277
+
278
+
The most convenient ID to use is the Item object for which the timer is operating, but you can use anything as the ID, e.g. a String, a number, the rule uid, etc.
279
+
280
+
```ruby
281
+
logger.info "Motion was detected"
282
+
FrontPorchLight.on
283
+
284
+
after 30.minutes, id:FrontPorchLightdo |timer|
285
+
logger.info "No more motion, turning off the light"
286
+
timer.id.off # We can do this because the Timer's id was set to the item object
287
+
# It is the same as FrontPorchLight.off
288
+
end
289
+
```
290
+
291
+
While it may seem straightforward, the JRuby helper library manages the timer and rescheduling internally to reduce the need for repetitive code.
292
+
Full flexibility to work and manipulate the timer is available for more advanced use.
293
+
294
+
:::
295
+
296
+
::::
297
+
174
298
Save and test that the rule sends the on and off commands as described.
175
299
176
300
### But only if: Conditions
177
301
178
302
Now we want the rule to only execute between sunset and 23:00.
179
-
Create a new Condition and choose ECMAScript 2021 as the language.
303
+
Create a new Condition and choose `ECMAScript` or `Ruby` as the language.
304
+
This doesn't have to be the same language as the one chosen for the Script Action above.
180
305
Just like with the Script Action, the Helper Library is available by default.
181
306
182
307
As discussed in the Blockly tutorial, the last line of a condition must evaluate to `true` or `false`.
183
308
When `true` the rule will run, otherwise it's skipped.
184
309
185
310
Sunset is available in an Item called `Sunset` and we need to test to see if `now` is between then and `23:00`.
311
+
312
+
:::: tabs
313
+
314
+
::: tab JS
315
+
186
316
In order to do that we need to convert the `Sunset` state to a JS-Joda date time.
187
317
188
318
Looking at the docs for [`Item`](/addons/automation/jsscripting/#items) we see that the Helper Library `Item` Class will return the String representation of the Item's state by default.
@@ -208,6 +338,30 @@ var endTime = time.ZonedDateTime.now().withHour(23).withMinute(0).withSecond(0).
[#between?](https://openhab.github.io/openhab-jruby/main/OpenHAB/CoreExt/Between.html#between%3F-instance_method) helper method is available on all Ruby and Java date, time, and Duration objects.
356
+
It takes a Ruby [Range](https://docs.ruby-lang.org/en/master/Range.html) as its argument, or two Date/Time objects to perform an inclusive range comparison.
357
+
358
+
Note that in JRuby, Date/Time and also DateTimeType objects (in the above example, the item's state) can all work interchangeably without any explicit conversions.
359
+
See [Working with Time](https://openhab.github.io/openhab-jruby/main/index.html#time) for more details.
360
+
361
+
:::
362
+
363
+
::::
364
+
211
365
## Advanced Topics
212
366
213
367
### Libraries
@@ -216,6 +370,10 @@ Most of the languages support installation and importing of third party librarie
216
370
Many of the languages will have special tools to download and install these libraries and there might be extra requirements to use them in openHAB.
217
371
See the add-on's docs and the forum for details on the automation add-on chosen.
218
372
373
+
:::: tabs
374
+
375
+
::: tab JS
376
+
219
377
For JS Scripting, `npm` is supported for the installation of third party libraries.
220
378
Run the `npm` command from the `$OH_CONF/automation/js` folder.
221
379
This will create a `node_modules` folder (if it doesn't already exist) and the library will be installed there.
@@ -231,6 +389,52 @@ That keeps it from being modified or overwritten by `npm` when upgrading or inst
231
389
There are several third party openHAB specific libraries on `npm` already.
232
390
Search the forum for details.
233
391
392
+
:::
393
+
394
+
::: tab JRuby
395
+
396
+
You can install JRuby-compatible Gems from [rubygems.org](https://rubygems.org) by listing them in the JRuby Script add-on [configurations](https://openhab.github.io/openhab-jruby/main/index.html#configuration).
397
+
Alternatively, the inline bundler is available from inside your script.
398
+
399
+
```ruby
400
+
gemfile do
401
+
source "https://rubygems.org"
402
+
gem "faraday", "~> 2.12", ">= 2.12.2"
403
+
end
404
+
```
405
+
406
+
[Personal libraries](https://openhab.github.io/openhab-jruby/main/index.html#shared-code) that contain your custom reusable constants, functions, data structures, and classes can be created and used inside your Script Actions and Conditions.
407
+
Simply save a `.rb` file that contain your code in `$OH_CONF/automation/ruby/lib/` folder, then `require` it in your script.
408
+
409
+
For example, a personal library file in `$OH_CONF/automation/ruby/lib/mylibs.rb`:
0 commit comments