openhab-scripting 2.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/workflow.yml +327 -0
- data/.gitignore +17 -0
- data/.java-version +1 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +113 -0
- data/Gemfile +28 -0
- data/Gemfile.lock +245 -0
- data/Guardfile +35 -0
- data/LICENSE +277 -0
- data/README.md +23 -0
- data/Rakefile +406 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/config/userdata/config/org/openhab/restauth.config +3 -0
- data/cucumber.yml +1 -0
- data/docs/_config.yml +135 -0
- data/docs/contributing/index.md +47 -0
- data/docs/examples/conversions.md +123 -0
- data/docs/examples/index.md +61 -0
- data/docs/index.md +19 -0
- data/docs/installation/index.md +26 -0
- data/docs/motivation/index.md +27 -0
- data/docs/usage/execution.md +9 -0
- data/docs/usage/execution/delay.md +48 -0
- data/docs/usage/execution/otherwise.md +30 -0
- data/docs/usage/execution/run.md +70 -0
- data/docs/usage/execution/triggered.md +48 -0
- data/docs/usage/guards.md +51 -0
- data/docs/usage/guards/between.md +30 -0
- data/docs/usage/guards/not_if.md +41 -0
- data/docs/usage/guards/only_if.md +40 -0
- data/docs/usage/index.md +11 -0
- data/docs/usage/items.md +66 -0
- data/docs/usage/items/contact.md +84 -0
- data/docs/usage/items/dimmer.md +147 -0
- data/docs/usage/items/groups.md +76 -0
- data/docs/usage/items/number.md +225 -0
- data/docs/usage/items/string.md +49 -0
- data/docs/usage/items/switch.md +85 -0
- data/docs/usage/misc.md +7 -0
- data/docs/usage/misc/actions.md +108 -0
- data/docs/usage/misc/duration.md +21 -0
- data/docs/usage/misc/gems.md +25 -0
- data/docs/usage/misc/logging.md +21 -0
- data/docs/usage/misc/metadata.md +128 -0
- data/docs/usage/misc/store_states.md +42 -0
- data/docs/usage/misc/time_of_day.md +69 -0
- data/docs/usage/misc/timers.md +67 -0
- data/docs/usage/rule.md +43 -0
- data/docs/usage/things.md +29 -0
- data/docs/usage/triggers.md +8 -0
- data/docs/usage/triggers/changed.md +57 -0
- data/docs/usage/triggers/channel.md +54 -0
- data/docs/usage/triggers/command.md +69 -0
- data/docs/usage/triggers/cron.md +19 -0
- data/docs/usage/triggers/every.md +76 -0
- data/docs/usage/triggers/updated.md +78 -0
- data/lib/openhab.rb +39 -0
- data/lib/openhab/configuration.rb +16 -0
- data/lib/openhab/core/cron.rb +27 -0
- data/lib/openhab/core/debug.rb +34 -0
- data/lib/openhab/core/dsl.rb +47 -0
- data/lib/openhab/core/dsl/actions.rb +107 -0
- data/lib/openhab/core/dsl/entities.rb +103 -0
- data/lib/openhab/core/dsl/gems.rb +29 -0
- data/lib/openhab/core/dsl/group.rb +91 -0
- data/lib/openhab/core/dsl/items/items.rb +39 -0
- data/lib/openhab/core/dsl/items/number_item.rb +217 -0
- data/lib/openhab/core/dsl/items/string_item.rb +102 -0
- data/lib/openhab/core/dsl/monkey_patch/actions/actions.rb +4 -0
- data/lib/openhab/core/dsl/monkey_patch/actions/script_thing_actions.rb +22 -0
- data/lib/openhab/core/dsl/monkey_patch/events.rb +5 -0
- data/lib/openhab/core/dsl/monkey_patch/events/item_command.rb +13 -0
- data/lib/openhab/core/dsl/monkey_patch/events/item_state_changed.rb +25 -0
- data/lib/openhab/core/dsl/monkey_patch/events/thing_status_info.rb +26 -0
- data/lib/openhab/core/dsl/monkey_patch/items/contact_item.rb +54 -0
- data/lib/openhab/core/dsl/monkey_patch/items/dimmer_item.rb +125 -0
- data/lib/openhab/core/dsl/monkey_patch/items/group_item.rb +27 -0
- data/lib/openhab/core/dsl/monkey_patch/items/items.rb +130 -0
- data/lib/openhab/core/dsl/monkey_patch/items/metadata.rb +259 -0
- data/lib/openhab/core/dsl/monkey_patch/items/switch_item.rb +86 -0
- data/lib/openhab/core/dsl/monkey_patch/ruby/number.rb +69 -0
- data/lib/openhab/core/dsl/monkey_patch/ruby/range.rb +46 -0
- data/lib/openhab/core/dsl/monkey_patch/ruby/ruby.rb +5 -0
- data/lib/openhab/core/dsl/monkey_patch/types/decimal_type.rb +24 -0
- data/lib/openhab/core/dsl/monkey_patch/types/on_off_type.rb +41 -0
- data/lib/openhab/core/dsl/monkey_patch/types/open_closed_type.rb +25 -0
- data/lib/openhab/core/dsl/monkey_patch/types/percent_type.rb +23 -0
- data/lib/openhab/core/dsl/monkey_patch/types/types.rb +7 -0
- data/lib/openhab/core/dsl/property.rb +85 -0
- data/lib/openhab/core/dsl/rule/channel.rb +41 -0
- data/lib/openhab/core/dsl/rule/cron.rb +115 -0
- data/lib/openhab/core/dsl/rule/guard.rb +99 -0
- data/lib/openhab/core/dsl/rule/item.rb +207 -0
- data/lib/openhab/core/dsl/rule/rule.rb +374 -0
- data/lib/openhab/core/dsl/rule/triggers.rb +77 -0
- data/lib/openhab/core/dsl/states.rb +63 -0
- data/lib/openhab/core/dsl/things.rb +93 -0
- data/lib/openhab/core/dsl/time_of_day.rb +203 -0
- data/lib/openhab/core/dsl/timers.rb +85 -0
- data/lib/openhab/core/dsl/types/quantity.rb +255 -0
- data/lib/openhab/core/dsl/units.rb +41 -0
- data/lib/openhab/core/duration.rb +69 -0
- data/lib/openhab/core/log.rb +175 -0
- data/lib/openhab/core/patch_load_path.rb +7 -0
- data/lib/openhab/core/startup_delay.rb +22 -0
- data/lib/openhab/osgi.rb +52 -0
- data/lib/openhab/version.rb +9 -0
- data/openhab-scripting.gemspec +30 -0
- data/openhab_rules/warmup.rb +5 -0
- metadata +157 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Delay
|
4
|
+
nav_order: 3
|
5
|
+
has_children: false
|
6
|
+
parent: Execution Blocks
|
7
|
+
grand_parent: Usage
|
8
|
+
---
|
9
|
+
|
10
|
+
|
11
|
+
# Delay
|
12
|
+
The delay property is a non thread-blocking element that is executed after, before, or between run blocks.
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
rule 'Delay sleeps between execution elements' do
|
16
|
+
on_start
|
17
|
+
run { logger.info("Sleeping") }
|
18
|
+
delay 5.seconds
|
19
|
+
run { logger.info("Awake") }
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
Like other execution blocks, multiple can exist in a single rule.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
rule 'Multiple delays can exist in a rule' do
|
27
|
+
on_start
|
28
|
+
run { logger.info("Sleeping") }
|
29
|
+
delay 5.seconds
|
30
|
+
run { logger.info("Sleeping Again") }
|
31
|
+
delay 5.seconds
|
32
|
+
run { logger.info("Awake") }
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
|
37
|
+
You can use ruby code in your rule across multiple execution blocks like a run and a delay.
|
38
|
+
```ruby
|
39
|
+
rule 'Dim a switch on system startup over 100 seconds' do
|
40
|
+
on_start
|
41
|
+
100.times do
|
42
|
+
run { DimmerSwitch.dim }
|
43
|
+
delay 1.second
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
```
|
48
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Otherwise
|
4
|
+
nav_order: 4
|
5
|
+
has_children: false
|
6
|
+
parent: Execution Blocks
|
7
|
+
grand_parent: Usage
|
8
|
+
---
|
9
|
+
|
10
|
+
|
11
|
+
# Otherwise
|
12
|
+
The otherwise property is the automation code that is executed when a rule is triggered and guards are not satisfied. This property accepts a block of code and executes it. The block is automatically passed an event object which can be used to access multiple properties about the triggering event.
|
13
|
+
|
14
|
+
## Event Properties
|
15
|
+
|
16
|
+
| Property | Description |
|
17
|
+
| -------- | -------------------------------- |
|
18
|
+
| item | Triggering item |
|
19
|
+
| state | Changed state of triggering item |
|
20
|
+
| last | Last state of triggering item |
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
rule 'Turn switch ON or OFF based on value of another switch' do
|
24
|
+
on_start
|
25
|
+
run { TestSwitch << ON }
|
26
|
+
otherwise { TestSwitch << OFF }
|
27
|
+
only_if { OtherSwitch == ON }
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Run
|
4
|
+
nav_order: 1
|
5
|
+
has_children: false
|
6
|
+
parent: Execution Blocks
|
7
|
+
grand_parent: Usage
|
8
|
+
---
|
9
|
+
|
10
|
+
|
11
|
+
# Run
|
12
|
+
The run property is the automation code that is executed when a rule is triggered. This property accepts a block of code and executes it. The block is automatically passed an event object which can be used to access multiple properties about the triggering event. The code for the automation can be entirely within the run block can call methods defined in the ruby script.
|
13
|
+
|
14
|
+
## State/Update Event Properties
|
15
|
+
The following properties exist when a run block is triggered from an [updated](#updated) or [changed](#changed) trigger.
|
16
|
+
|
17
|
+
| Property | Description |
|
18
|
+
| -------- | -------------------------------- |
|
19
|
+
| item | Triggering item |
|
20
|
+
| state | Changed state of triggering item |
|
21
|
+
| last | Last state of triggering item |
|
22
|
+
|
23
|
+
## Command Event Properties
|
24
|
+
The following properties exist when a run block is triggered from a [received_command](#received_command) trigger.
|
25
|
+
|
26
|
+
| Property | Description |
|
27
|
+
| -------- | -------------------- |
|
28
|
+
| command | Command sent to item |
|
29
|
+
|
30
|
+
## Thing Event Properties
|
31
|
+
The following properties exist when a run block is triggered from an [updated](#updated) or [changed](#changed) trigger on a Thing.
|
32
|
+
|
33
|
+
| Property | Description |
|
34
|
+
| -------- | ----------------------------------------------------------------- |
|
35
|
+
| uid | UID of the triggered Thing |
|
36
|
+
| last | Status before Change for thing (only valid on Change, not update) |
|
37
|
+
| status | Current status of the triggered Thing |
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
`{}` Style used for single line blocks
|
42
|
+
```ruby
|
43
|
+
rule 'Access Event Properties' do
|
44
|
+
changed TestSwitch
|
45
|
+
run { |event| logger.info("#{event.item.id} triggered from #{event.last} to #{event.state}") }
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
`do/end` style used for multi-line blocks
|
50
|
+
```ruby
|
51
|
+
rule 'Multi Line Run Block' do
|
52
|
+
changed TestSwitch
|
53
|
+
run do |event|
|
54
|
+
logger.info("#{event.item.id} triggered")
|
55
|
+
logger.info("from #{event.last}") if event.last
|
56
|
+
logger.info("to #{event.state}") if event.state
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
Rules can have multiple run blocks and they are executed in order, Useful when used in combination with delay
|
62
|
+
```ruby
|
63
|
+
rule 'Multiple Run Blocks' do
|
64
|
+
changed TestSwitch
|
65
|
+
run { |event| logger.info("#{event.item.id} triggered") }
|
66
|
+
run { |event| logger.info("from #{event.last}") if event.last }
|
67
|
+
run { |event| logger.info("to #{event.state}") if event.state }
|
68
|
+
end
|
69
|
+
|
70
|
+
```
|
@@ -0,0 +1,48 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Triggered
|
4
|
+
nav_order: 2
|
5
|
+
has_children: false
|
6
|
+
parent: Execution Blocks
|
7
|
+
grand_parent: Usage
|
8
|
+
---
|
9
|
+
|
10
|
+
# Triggered
|
11
|
+
This property is the same as the run property except rather than passing an event object to the automation block the triggered item is passed. This enables optimizations for simple cases and supports ruby's [pretzel colon `&:` operator.](https://medium.com/@dcjones/the-pretzel-colon-75df46dde0c7)
|
12
|
+
|
13
|
+
## Examples
|
14
|
+
```ruby
|
15
|
+
rule 'Triggered has access directly to item triggered' do
|
16
|
+
changed TestSwitch
|
17
|
+
triggered { |item| logger.info("#{item.id} triggered") }
|
18
|
+
end
|
19
|
+
|
20
|
+
```
|
21
|
+
|
22
|
+
Triggered items are highly useful when working with groups
|
23
|
+
```ruby
|
24
|
+
#Switches is a group of Switch items
|
25
|
+
|
26
|
+
rule 'Triggered item is item changed when a group item is changed.' do
|
27
|
+
changed Switches.items
|
28
|
+
triggered { |item| logger.info("Switch #{item.id} changed to #{item}")}
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
rule 'Turn off any switch that changes' do
|
33
|
+
changed Switches.items
|
34
|
+
triggered(&:off)
|
35
|
+
end
|
36
|
+
|
37
|
+
```
|
38
|
+
|
39
|
+
Like other execution blocks, multiple triggered blocks are supported in a single rule
|
40
|
+
```ruby
|
41
|
+
rule 'Turn a switch off and log it, 5 seconds after turning it on' do
|
42
|
+
changed Switches.items, to: ON
|
43
|
+
delay 5.seconds
|
44
|
+
triggered(&:off)
|
45
|
+
triggered {|item| logger.info("#{item.label} turned off") }
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Guards
|
4
|
+
nav_order: 3
|
5
|
+
has_children: true
|
6
|
+
parent: Usage
|
7
|
+
---
|
8
|
+
|
9
|
+
# Guards
|
10
|
+
|
11
|
+
Guards exist to only permit rules to run if certain conditions are satisfied. Think of these as declarative if statements that keep the run block free of conditional logic, although you can of course still use conditional logic in run blocks if you prefer.
|
12
|
+
|
13
|
+
only_if and not_if guards that are provided objects rather than blocks automatically check for the 'truthyness' of the supplied object.
|
14
|
+
|
15
|
+
Truthyness for Item types:
|
16
|
+
|
17
|
+
| Item | Truthy when |
|
18
|
+
| ------- | ----------- |
|
19
|
+
| Switch | state == ON |
|
20
|
+
| Dimmer | state != 0 |
|
21
|
+
| Contact | Not Defined |
|
22
|
+
| String | Not Blank |
|
23
|
+
| Number | state != 0 |
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
## Guard Combination
|
28
|
+
|
29
|
+
only_if and not_if can be used on the same rule, both be satisfied for a rule to execute.
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
rule 'Set OutsideDimmer to 50% if LightSwtich turned on and OtherSwitch is OFF and Door is CLOSED' do
|
33
|
+
changed LightSwitch, to: ON
|
34
|
+
run { OutsideDimmer << 50 }
|
35
|
+
only_if { Door == CLOSED }
|
36
|
+
not_if OtherSwitch
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
|
41
|
+
#### Guard Event Access
|
42
|
+
Guards have access to event information.
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
rule 'Set OutsideDimmer to 50% if any switch in group Switches starting with Outside is switched On' do
|
46
|
+
changed Switches.items, to: ON
|
47
|
+
run { OutsideDimmer << 50 }
|
48
|
+
only_if { |event| event.item.name.start_with? 'Outside' }
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Between
|
4
|
+
nav_order: 3
|
5
|
+
has_children: false
|
6
|
+
parent: Guards
|
7
|
+
grand_parent: Usage
|
8
|
+
---
|
9
|
+
|
10
|
+
# between
|
11
|
+
Only runs the rule if the current time is in the provided range
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
rule 'Log an entry if started between 3:30:04 and midnight using strings' do
|
15
|
+
on_start
|
16
|
+
run { logger.info ("Started at #{TimeOfDay.now}")}
|
17
|
+
between '3:30:04'..MIDNIGHT
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
or
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
rule 'Log an entry if started between 3:30:04 and midnight using TimeOfDay objects' do
|
25
|
+
on_start
|
26
|
+
run { logger.info ("Started at #{TimeOfDay.now}")}
|
27
|
+
between TimeOfDay.new(h: 3, m: 30, s: 4)..MIDNIGHT
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Not If
|
4
|
+
nav_order: 2
|
5
|
+
has_children: false
|
6
|
+
parent: Guards
|
7
|
+
grand_parent: Usage
|
8
|
+
---
|
9
|
+
|
10
|
+
#### not_if
|
11
|
+
|
12
|
+
not_if allows prevents execution of rules when result is false and prevents when true
|
13
|
+
|
14
|
+
```
|
15
|
+
rule 'Set OutsideDimmer to 50% if LightSwtich turned on and OtherSwitch is OFF' do
|
16
|
+
changed LightSwitch, to: ON
|
17
|
+
run { OutsideDimmer << 50 }
|
18
|
+
not_if { OtherSwitch == ON }
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
Because not_if uses 'truthy?' on non-block objects the above rule can also be written like this:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
rule 'Set OutsideDimmer to 50% if LightSwtich turned on and OtherSwitch is OFF' do
|
26
|
+
changed LightSwitch, to: ON
|
27
|
+
run { OutsideDimmer << 50 }
|
28
|
+
not_if OtherSwitch
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
Multiple not_if statements can be used and if **any** of them are not satisfied the rule will not run.
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
rule 'Set OutsideDimmer to 50% if LightSwtich turned on and OtherSwitch is OFF and Door is not CLOSED' do
|
36
|
+
changed LightSwitch, to: ON
|
37
|
+
run { OutsideDimmer << 50 }
|
38
|
+
not_if OtherSwitch
|
39
|
+
not_if { Door == CLOSED }
|
40
|
+
end
|
41
|
+
```
|
@@ -0,0 +1,40 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Only If
|
4
|
+
nav_order: 1
|
5
|
+
has_children: false
|
6
|
+
parent: Guards
|
7
|
+
grand_parent: Usage
|
8
|
+
---
|
9
|
+
|
10
|
+
# only_if
|
11
|
+
only_if allows rule execution when result is true and prevents when false.
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
rule 'Set OutsideDimmer to 50% if LightSwtich turned on and OtherSwitch is also ON' do
|
15
|
+
changed LightSwitch, to: ON
|
16
|
+
run { OutsideDimmer << 50 }
|
17
|
+
only_if { OtherSwitch == ON }
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
Because only_if uses 'truthy?' on non-block objects the above rule can also be written like this:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
rule 'Set OutsideDimmer to 50% if LightSwtich turned on and OtherSwitch is also ON' do
|
25
|
+
changed LightSwitch, to: ON
|
26
|
+
run { OutsideDimmer << 50 }
|
27
|
+
only_if OtherSwitch
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
multiple only_if statements can be used and **all** must be true for the rule to run.
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
rule 'Set OutsideDimmer to 50% if LightSwtich turned on and OtherSwitch is also ON and Door is closed' do
|
35
|
+
changed LightSwitch, to: ON
|
36
|
+
run { OutsideDimmer << 50 }
|
37
|
+
only_if OtherSwitch
|
38
|
+
only_if { Door == CLOSED }
|
39
|
+
end
|
40
|
+
```
|
data/docs/usage/index.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Usage
|
4
|
+
nav_order: 4
|
5
|
+
has_children: true
|
6
|
+
---
|
7
|
+
|
8
|
+
|
9
|
+
## Rules Requirements
|
10
|
+
1. Place Ruby rules files in `ruby/personal/` subdirectory for OpenHAB scripted automation. See [OpenHAB documentation](https://www.openhab.org/docs/configuration/jsr223.html#script-locations) for parent directory location.
|
11
|
+
2. Put `require 'openhab'` at the top of any Ruby based rules file.
|
data/docs/usage/items.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Items
|
4
|
+
nav_order: 4
|
5
|
+
has_children: true
|
6
|
+
parent: Usage
|
7
|
+
---
|
8
|
+
|
9
|
+
|
10
|
+
# Items
|
11
|
+
Items can be directly accessed, compared, etc, without any special accessors. You may use the item name anywhere within the code and it will automatically be loaded.
|
12
|
+
|
13
|
+
All items can be accessed as an enumerable the `items` method.
|
14
|
+
|
15
|
+
| Method | Description |
|
16
|
+
| ------------------ | ------------------------------------------------------------------------------ |
|
17
|
+
| [] | Get a specific item by name, this syntax can be used to dynamically load items |
|
18
|
+
| enumerable methods | All methods [here](https://ruby-doc.org/core-2.5.0/Enumerable.html) |
|
19
|
+
|
20
|
+
## Examples
|
21
|
+
|
22
|
+
Item Definition
|
23
|
+
```
|
24
|
+
Dimmer DimmerTest "Test Dimmer"
|
25
|
+
Switch SwitchTest "Test Switch"
|
26
|
+
|
27
|
+
```
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
logger.info("Item Count: #{items.count}") # Item Count: 2
|
31
|
+
logger.info("Items: #{items.sort_by(&:label).map(&:label).join(', ')}") #Items: Test Dimmer, Test Switch'
|
32
|
+
```
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
rule 'Use dynamic item lookup to increase related dimmer brightness when switch is turned on' do
|
36
|
+
changed SwitchTest, to: ON
|
37
|
+
triggered { |item| items[item.name.gsub('Switch','Dimmer')].brighten(10) }
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
## All Items
|
42
|
+
Item types have methods added to them to make it flow naturally within the a ruby context. All methods of the OpenHAB item are available plus the additional methods described below.
|
43
|
+
|
44
|
+
|
45
|
+
| Method | Description | Example |
|
46
|
+
| ------- | ------------------------------------------------- | ------------------------------------------------------------ |
|
47
|
+
| << | Sends command to item | `VirtualSwich << ON` |
|
48
|
+
| command | alias for shovel operator (<<) | `VirtualSwich.command(ON)` |
|
49
|
+
| update | Sends update to an item | `VirtualSwitch.update(ON)` |
|
50
|
+
| id | Returns label or item name if no label | `logger.info(#{item.id})` |
|
51
|
+
| undef? | Returns true if the state of the item is UNDEF | `logger.info("SwitchTest is UNDEF") if SwitchTest.undef?` |
|
52
|
+
| null? | Returns true if the state of the item is NULL | `logger.info("SwitchTest is NULL") if SwitchTest.null?` |
|
53
|
+
| state? | Returns true if the state is not UNDEF or NULL | `logger.info("SwitchTest has a state") if SwitchTest.state?` |
|
54
|
+
| state | Returns state of the item or nil if UNDEF or NULL | `logger.info("SwitchTest state #{SwitchTest.state}")` |
|
55
|
+
| to_s | Returns state in string format | `logger.info(#{item.id}: #{item})` |
|
56
|
+
|
57
|
+
State returns nil instead of UNDEF or NULL so that it can be used with with [Ruby safe navigation operator](https://ruby-doc.org/core-2.6/doc/syntax/calling_methods_rdoc.html) `&.` Use `undef?` or `null?` to check for those states.
|
58
|
+
|
59
|
+
To operate across an arbitrary collection of items you can place them in an [array](https://ruby-doc.org/core-2.5.0/Array.html) and execute methods against the array.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
number_items = [Livingroom_Temp, Bedroom_Temp]
|
63
|
+
logger.info("Max is #{number_items.max}")
|
64
|
+
logger.info("Min is #{number_items.min}")
|
65
|
+
```
|
66
|
+
|