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
data/cucumber.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
default: --publish-quiet
|
data/docs/_config.yml
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# Welcome to Jekyll!
|
2
|
+
#
|
3
|
+
# This config file is meant for settings that affect your whole site, values
|
4
|
+
# which you are expected to set up once and rarely edit after that. If you find
|
5
|
+
# yourself editing these this file very often, consider using Jekyll's data files
|
6
|
+
# feature for the data you need to update frequently.
|
7
|
+
#
|
8
|
+
# For technical reasons, this file is *NOT* reloaded automatically when you use
|
9
|
+
# 'jekyll serve'. If you change this file, please restart the server process.
|
10
|
+
|
11
|
+
# Site settings
|
12
|
+
# These are used to personalize your new site. If you look in the HTML files,
|
13
|
+
# you will see them accessed via {{ site.title }}, {{ site.github_repo }}, and so on.
|
14
|
+
# You can create any custom variable you would like, and they will be accessible
|
15
|
+
# in the templates via {{ site.myvariable }}.
|
16
|
+
|
17
|
+
title: OpenHAB JRuby Script Library
|
18
|
+
description: JRuby Scripting Helper Library
|
19
|
+
baseurl: "/openhab-jruby/" # the subpath of your site, e.g. /blog
|
20
|
+
#url: "https://boc-tothefuture.github.io/" # the base hostname & protocol for your site, e.g. http://example.com
|
21
|
+
|
22
|
+
source: "docs/"
|
23
|
+
permalink: pretty
|
24
|
+
exclude: ["node_modules/", "*.gemspec", "*.gem", "Gemfile", "Gemfile.lock", "package.json", "package-lock.json", "script/", "LICENSE.txt", "lib/", "bin/", "README.md", "Rakefile"
|
25
|
+
, "docs/tests/"
|
26
|
+
]
|
27
|
+
|
28
|
+
# Build settings
|
29
|
+
markdown: kramdown
|
30
|
+
theme: just-the-docs
|
31
|
+
plugins:
|
32
|
+
- jekyll-feed
|
33
|
+
|
34
|
+
remote_theme: pmarsceill/just-the-docs
|
35
|
+
|
36
|
+
|
37
|
+
# Regression tests
|
38
|
+
# By default, the pages in /docs/tests are excluded when the ste is built.
|
39
|
+
# To include them, comment-out the relevant line above.
|
40
|
+
# Uncommenting the following line doesn't work - see https://github.com/jekyll/jekyll/issues/4791
|
41
|
+
# include: ["docs/tests/"]
|
42
|
+
|
43
|
+
# Set a path/url to a logo that will be displayed instead of the title
|
44
|
+
#logo: "/assets/images/just-the-docs.png"
|
45
|
+
|
46
|
+
# Enable or disable the site search
|
47
|
+
# Supports true (default) or false
|
48
|
+
search_enabled: true
|
49
|
+
search:
|
50
|
+
# Split pages into sections that can be searched individually
|
51
|
+
# Supports 1 - 6, default: 2
|
52
|
+
heading_level: 2
|
53
|
+
# Maximum amount of previews per search result
|
54
|
+
# Default: 3
|
55
|
+
previews: 2
|
56
|
+
# Maximum amount of words to display before a matched word in the preview
|
57
|
+
# Default: 5
|
58
|
+
preview_words_before: 3
|
59
|
+
# Maximum amount of words to display after a matched word in the preview
|
60
|
+
# Default: 10
|
61
|
+
preview_words_after: 3
|
62
|
+
# Set the search token separator
|
63
|
+
# Default: /[\s\-/]+/
|
64
|
+
# Example: enable support for hyphenated search words
|
65
|
+
tokenizer_separator: /[\s/]+/
|
66
|
+
# Display the relative url in search results
|
67
|
+
# Supports true (default) or false
|
68
|
+
rel_url: true
|
69
|
+
# Enable or disable the search button that appears in the bottom right corner of every page
|
70
|
+
# Supports true or false (default)
|
71
|
+
button: false
|
72
|
+
|
73
|
+
# Enable or disable heading anchors
|
74
|
+
heading_anchors: true
|
75
|
+
|
76
|
+
# Aux links for the upper right navigation
|
77
|
+
#aux_links:
|
78
|
+
# "Just the Docs on GitHub":
|
79
|
+
# - "//github.com/pmarsceill/just-the-docs"
|
80
|
+
|
81
|
+
# Makes Aux links open in a new tab. Default is false
|
82
|
+
aux_links_new_tab: false
|
83
|
+
|
84
|
+
# Sort order for navigation links
|
85
|
+
# nav_sort: case_insensitive # default, equivalent to nil
|
86
|
+
nav_sort: case_sensitive # Capital letters sorted before lowercase
|
87
|
+
|
88
|
+
# Footer content
|
89
|
+
# appears at the bottom of every page's main content
|
90
|
+
|
91
|
+
# Back to top link
|
92
|
+
back_to_top: true
|
93
|
+
back_to_top_text: "Back to top"
|
94
|
+
|
95
|
+
footer_content: "Copyright © 2017-2020 Patrick Marsceill. Distributed by an <a href=\"https://github.com/pmarsceill/just-the-docs/tree/master/LICENSE.txt\">MIT license.</a>"
|
96
|
+
|
97
|
+
# Footer last edited timestamp
|
98
|
+
last_edit_timestamp: true # show or hide edit time - page must have `last_modified_date` defined in the frontmatter
|
99
|
+
last_edit_time_format: "%b %e %Y at %I:%M %p" # uses ruby's time format: https://ruby-doc.org/stdlib-2.7.0/libdoc/time/rdoc/Time.html
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
# Footer "Edit this page on GitHub" link text
|
104
|
+
gh_edit_link: true # show or hide edit this page link
|
105
|
+
gh_edit_link_text: "Edit this page on GitHub"
|
106
|
+
gh_edit_repository: "https://github.com/pmarsceill/just-the-docs" # the github URL for your repo
|
107
|
+
gh_edit_branch: "main" # the branch that your docs is served from
|
108
|
+
# gh_edit_source: docs # the source that your files originate from
|
109
|
+
gh_edit_view_mode: "tree" # "tree" or "edit" if you want the user to jump into the editor immediately
|
110
|
+
|
111
|
+
# Color scheme currently only supports "dark", "light"/nil (default), or a custom scheme that you define
|
112
|
+
color_scheme: nil
|
113
|
+
|
114
|
+
# Google Analytics Tracking (optional)
|
115
|
+
# e.g, UA-1234567-89
|
116
|
+
ga_tracking: UA-80492189-2
|
117
|
+
ga_tracking_anonymize_ip: true # Use GDPR compliant Google Analytics settings (true/nil by default)
|
118
|
+
|
119
|
+
plugins:
|
120
|
+
- jekyll-seo-tag
|
121
|
+
|
122
|
+
kramdown:
|
123
|
+
syntax_highlighter_opts:
|
124
|
+
block:
|
125
|
+
line_numbers: false
|
126
|
+
|
127
|
+
compress_html:
|
128
|
+
clippings: all
|
129
|
+
comments: all
|
130
|
+
endings: all
|
131
|
+
startings: []
|
132
|
+
blanklines: false
|
133
|
+
profile: false
|
134
|
+
# ignore:
|
135
|
+
# envs: all
|
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Contributing
|
4
|
+
nav_order: 5
|
5
|
+
has_children: false
|
6
|
+
---
|
7
|
+
|
8
|
+
|
9
|
+
# Contributions
|
10
|
+
|
11
|
+
Contributions, issues and pull requests are welcome. Please visit the [GitHub home](https://github.com/boc-tothefuture/openhab-jruby) for this project.
|
12
|
+
|
13
|
+
|
14
|
+
# License
|
15
|
+
This code is under the [eclipse v2 license](https://www.eclipse.org/legal/epl-2.0/)
|
16
|
+
|
17
|
+
|
18
|
+
# Source
|
19
|
+
JRuby Scripting OpenHAB is GitHub repo is [here](https://github.com/boc-tothefuture/openhab-jruby). Code is under the eclipse v2 license.
|
20
|
+
|
21
|
+
|
22
|
+
# Development Environment Setup
|
23
|
+
The development process has been tested on MacOS, others operating systems may work.
|
24
|
+
|
25
|
+
1. Install Ruby 2.5.8 - Recommended method is using [rbenv](https://github.com/rbenv/rbenv#installation)
|
26
|
+
2. Fork [the repo](https://github.com/boc-tothefuture/openhab-jruby) and clone it
|
27
|
+
3. Install [bundler](https://bundler.io/)
|
28
|
+
4. Run `bundler install` from inside of the repo directory
|
29
|
+
5. Run `bundle openhab:setup` from inside of the repo directory. This will download a copy of OpenHAB local in your development environment, start it and prepare it for JRuby OpenHAB Scripting Development
|
30
|
+
|
31
|
+
# Documentation
|
32
|
+
Documentation is written in [Yard](https://yardoc.org/) and the current documentation for this project is available [here](../yard).
|
33
|
+
|
34
|
+
|
35
|
+
# Development Process
|
36
|
+
1. Create a branch for your contribution
|
37
|
+
2. Write your tests the project uses [Behavior Driven Development](https://en.wikipedia.org/wiki/Behavior-driven_development) with [Cucumber](https://cucumber.io/). The features directory has many examples. Feel free ask in your PR if you need help.
|
38
|
+
3. Write your code
|
39
|
+
4. Verify your tests now pass by running `bundle exec cucumber features/<your feature file>.feature`
|
40
|
+
5. Update the documentation, run `bundle exec rake docs` to view the rendered documentation locally
|
41
|
+
6. Lint your code with `bundle exec rake lint` and ensure you have created any [Rubocop](https://github.com/rubocop-hq/rubocop) or [cuke lint](https://github.com/enkessler/cuke_linter) violations
|
42
|
+
7. Update the [Changelog.md](https://github.com/boc-tothefuture/openhab-jruby/blob/main/CHANGELOG.md) describing your change using [this format](https://keepachangelog.com/en/1.0.0/)
|
43
|
+
8. Update the version in 'lib/openhab/version.rb' with the new version number, this project uses [SemVer](https://semver.org/) for versioning
|
44
|
+
9. Submit your PR!
|
45
|
+
|
46
|
+
If you get stuck or need help along the way, please open an issue.
|
47
|
+
|
@@ -0,0 +1,123 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Rule Conversions
|
4
|
+
nav_order: 1
|
5
|
+
has_children: false
|
6
|
+
parent: Examples
|
7
|
+
---
|
8
|
+
|
9
|
+
|
10
|
+
## Conversion Examples
|
11
|
+
|
12
|
+
DSL
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
rule 'Snap Fan to preset percentages'
|
16
|
+
when Member of CeilingFans changed
|
17
|
+
then
|
18
|
+
val fan = triggeringItem
|
19
|
+
val name = String.join(" ", fan.name.replace("LoadLevelStatus","").split("(?<!^)(?=[A-Z])"))
|
20
|
+
logInfo("Fan", "Ceiling fan group rule triggered for {}, value {}", name,fan.state)
|
21
|
+
switch fan {
|
22
|
+
case fan.state >0 && fan.state < 25 : {
|
23
|
+
logInfo("Fan", "Snapping {} to 25%", name)
|
24
|
+
sendCommand(fan, 25)
|
25
|
+
}
|
26
|
+
case fan.state > 25 && fan.state < 66 : {
|
27
|
+
logInfo("Fan", "Snapping {} to 66%", name)
|
28
|
+
sendCommand(fan, 66)
|
29
|
+
}
|
30
|
+
case fan.state > 66 && fan.state < 100 : {
|
31
|
+
logInfo("Fan", "Snapping {} to 100%", name)
|
32
|
+
sendCommand(fan, 100)
|
33
|
+
}
|
34
|
+
default: {
|
35
|
+
logInfo("Fan", "{} set to snapped percentage, no action taken", name)
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Ruby
|
42
|
+
```ruby
|
43
|
+
rule 'Snap Fan to preset percentages' do
|
44
|
+
changed(*CeilingFans)
|
45
|
+
triggered do |item|
|
46
|
+
snapped = case item
|
47
|
+
when 0...25 then 25
|
48
|
+
when 26...66 then 66
|
49
|
+
when 67...100 then 100
|
50
|
+
end
|
51
|
+
if snapped
|
52
|
+
logger.info("Snapping fan #{item.id} to #{snapped}")
|
53
|
+
item << snapped
|
54
|
+
else
|
55
|
+
logger.info("#{item.id} set to snapped percentage, no action taken.")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
Python
|
62
|
+
```python
|
63
|
+
@rule("Use Supplemental Heat In Office")
|
64
|
+
@when("Item Office_Temperature changed")
|
65
|
+
@when("Item Thermostats_Upstairs_Temp changed")
|
66
|
+
@when("Item Office_Occupied changed")
|
67
|
+
@when("Item OfficeDoor changed")
|
68
|
+
def office_heater(event):
|
69
|
+
office_temp = ir.getItem("Office_Temperature").getStateAs(QuantityType).toUnit(ImperialUnits.FAHRENHEIT).floatValue()
|
70
|
+
hall_temp = items["Thermostats_Upstairs_Temp"].floatValue()
|
71
|
+
therm_status = items["Thermostats_Upstairs_Status"].intValue()
|
72
|
+
heat_set = items["Thermostats_Upstairs_Heat_Set"].intValue()
|
73
|
+
occupied = items["Office_Occupied"]
|
74
|
+
door = items["OfficeDoor"]
|
75
|
+
difference = hall_temp - office_temp
|
76
|
+
logging.warn("Office Temperature: {} Upstairs Hallway Temperature: {} Differnce: {}".format(office_temp,hall_temp,difference))
|
77
|
+
logging.warn("Themostat Status: {} Heat Set: {}".format(therm_status,heat_set))
|
78
|
+
logging.warn("Office Occupied: {}".format(occupied))
|
79
|
+
logging.warn("Office Door: {}".format(door))
|
80
|
+
degree_difference = 2.0
|
81
|
+
trigger = False
|
82
|
+
if heat_set > office_temp:
|
83
|
+
if difference > degree_difference:
|
84
|
+
if occupied == ON:
|
85
|
+
if True:
|
86
|
+
if therm_status == 0:
|
87
|
+
if door == CLOSED:
|
88
|
+
trigger = True
|
89
|
+
else:
|
90
|
+
logging.warn("Door Open, no action taken")
|
91
|
+
else:
|
92
|
+
logging.warn("HVAC on, no action taken")
|
93
|
+
else:
|
94
|
+
logging.warn("Office unoccupied, no action taken")
|
95
|
+
else:
|
96
|
+
logging.warn("Thermstat and office temperature difference {} is less than {} degrees, no action taken".format(difference, degree_difference))
|
97
|
+
else:
|
98
|
+
logging.warn("Heat set lower than office temp, no action taken".format(difference, degree_difference))
|
99
|
+
|
100
|
+
|
101
|
+
if trigger:
|
102
|
+
logging.warn("Turning on heater")
|
103
|
+
events.sendCommand("Lights_Office_Outlet","ON")
|
104
|
+
else:
|
105
|
+
logging.warn("Turning off heater")
|
106
|
+
events.sendCommand("Lights_Office_Outlet","OFF")
|
107
|
+
```
|
108
|
+
|
109
|
+
|
110
|
+
Ruby
|
111
|
+
```ruby
|
112
|
+
rule 'Use supplemental heat in office' do
|
113
|
+
changed Office_Temperature, Thermostats_Upstairs_Temp, Office_Occupied, OfficeDoor
|
114
|
+
run { Lights_Office_Outlet << ON }
|
115
|
+
only_if Office_Occupied
|
116
|
+
only_if { OfficeDoor == CLOSED }
|
117
|
+
only_if { Thermostate_Upstairs_Heat_Set > Office_Temperature }
|
118
|
+
only_if { unit(°F') { Thermostat_Upstairs_Temp - Office_Temperature > 2 } }
|
119
|
+
otherwise { Lights_Office_Outlet << OFF if Lights_Office_Outlet.on? }
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Examples
|
4
|
+
nav_order: 5
|
5
|
+
has_children: true
|
6
|
+
---
|
7
|
+
|
8
|
+
## Examples
|
9
|
+
|
10
|
+
### Log "Rule *name* executed" an entry every minute
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
rule 'Simple' do
|
14
|
+
every :minute
|
15
|
+
run { logger.info "Rule #{name} executed" }
|
16
|
+
end
|
17
|
+
|
18
|
+
```
|
19
|
+
|
20
|
+
### The rule definition itself is just ruby code
|
21
|
+
|
22
|
+
Meaning you can use code itself to generate your rules*
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
rule 'Log whenever a Virtual Switch Changes' do
|
26
|
+
items.select { |item| item.is_a? Switch }
|
27
|
+
.select { |item| item.label&.include? 'Virtual' }
|
28
|
+
.each do |item|
|
29
|
+
changed item
|
30
|
+
end
|
31
|
+
|
32
|
+
run { |event| logger.info "#{event.item.id} changed from #{event.last} to #{event.state}" }
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
Which is the same as
|
37
|
+
```ruby
|
38
|
+
virtual_switches = items.select { |item| item.is_a? Switch }
|
39
|
+
.select { |item| item.label&.include? 'Virtual' }
|
40
|
+
|
41
|
+
rule 'Log whenever a Virtual Switch Changes 2' do
|
42
|
+
changed virtual_switches
|
43
|
+
run { |event| logger.info "#{event.item.id} changed from #{event.last} to #{event.state} 2" }
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
This will accomplish the same thing, but create a new rule for each virtual switch*
|
48
|
+
```ruby
|
49
|
+
virtual_switches = items.select { |item| item.is_a? Switch }
|
50
|
+
.select { |item| item.label&.include? 'Virtual' }
|
51
|
+
|
52
|
+
virtual_switches.each do |switch|
|
53
|
+
rule "Log whenever a #{switch.label} Changes" do
|
54
|
+
changed switch
|
55
|
+
run { |event| logger.info "#{event.item.id} changed from #{event.last} to #{event.state} 2" }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
* Take care when doing this as the the items/groups are processed when the rules file is processed, meaning that new items/groups will not automatically generate new rules.
|
61
|
+
|
data/docs/index.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: OpenHAB JRuby Scripting
|
4
|
+
nav_order: 1
|
5
|
+
has_children: false
|
6
|
+
---
|
7
|
+
|
8
|
+
|
9
|
+
# OpenHAB JRuby Scripting
|
10
|
+
|
11
|
+
The OpenHAB JRuby scripting helpers bring the power of the Ruby language to OpenHAB. Rather than being a pure pass-through to OpenHAB, they provide a Ruby-like experience when building automation rules within OpenHAB.
|
12
|
+
|
13
|
+
|
14
|
+
## Discussion
|
15
|
+
Please see [this thread](https://community.openhab.org/t/jruby-openhab-rules-system/110598) on the OpenHAB forum for further discussion. Ideas and suggestions are welcome.
|
16
|
+
|
17
|
+
|
18
|
+
## State
|
19
|
+
This is an alpha and syntax and all elements are subject to change as the library evolves.
|
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Installation
|
4
|
+
nav_order: 3
|
5
|
+
has_children: false
|
6
|
+
---
|
7
|
+
|
8
|
+
## Prerequisites
|
9
|
+
1. OpenHAB 3
|
10
|
+
2. The JRuby Scripting Language Addon
|
11
|
+
3. This scripting library
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
1. Install the latest Jruby Scripting Language Addon from [here](https://github.com/boc-tothefuture/openhab-jruby/releases/) to the folder `<openhab_base_dir>/addons/`
|
17
|
+
2. Create directory for JRuby Libraries `<openhab_base_dir>/conf/automation/lib/ruby/lib`
|
18
|
+
3. Create directory for Ruby Gems `<openhab_base_dir>/conf/automation/lib/ruby/gem_home`
|
19
|
+
4. Download latest JRuby Libraries from [here](https://github.com/boc-tothefuture/openhab-jruby/releases/)
|
20
|
+
5. Install libraries in `<openhab_base_dir>/conf/automation/lib/ruby/lib`
|
21
|
+
6. Update OpenHAB start.sh with the following environment variables so that the library can be loaded and gems can be installed
|
22
|
+
```
|
23
|
+
export RUBYLIB=<openhab_base_dir>/conf/automation/lib/ruby/lib
|
24
|
+
export GEM_HOME=<openhab_base_dir>/conf/automation/lib/ruby/gem_home
|
25
|
+
```
|
26
|
+
7. Restart OpenHAB
|
@@ -0,0 +1,27 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Motivation
|
4
|
+
nav_order: 2
|
5
|
+
has_children: false
|
6
|
+
---
|
7
|
+
|
8
|
+
## Design points
|
9
|
+
- Create an intuitive method of defining rules and automation
|
10
|
+
- Rule language should "flow" in a way that you can read the rules out loud
|
11
|
+
- Abstract away complexities of OpenHAB (Timers, Item.state vs Item)
|
12
|
+
- Enable all the power of Ruby and OpenHAB
|
13
|
+
- Create a Frictionless experience for building automation
|
14
|
+
- The common, yet tricky tasks are abstracted and made easy. e.g. Running a rule between only certain hours of the day
|
15
|
+
- Tested
|
16
|
+
- Designed and tested using [Behavior Driven Development](https://en.wikipedia.org/wiki/Behavior-driven_development) with [Cucumber](https://cucumber.io/)
|
17
|
+
- Current tests are [here](https://github.com/boc-tothefuture/openhab-jruby/tree/main/features) Reviewing them is a great way to explore the language features
|
18
|
+
- Extensible
|
19
|
+
- Anyone should be able to customize and add/remove core language features
|
20
|
+
- Easy access to the Ruby ecosystem in rules through ruby gems.
|
21
|
+
|
22
|
+
## Why Ruby?
|
23
|
+
- Ruby is designed for programmer productivity with the idea that programming should be fun for programmers.
|
24
|
+
- Ruby emphasizes the necessity for software to be understood by humans first and computers second.
|
25
|
+
- For me, automation is a hobby, I want to enjoy writing automation not fight compilers and interpreters
|
26
|
+
- Rich ecosystem of tools, including things like Rubocop to help developers create good code and cucumber to test the libraries
|
27
|
+
- Ruby is really good at letting one express intent and creating a DSL within ruby to make that expression easier.
|