openhab-jrubyscripting 5.0.0.rc4 → 5.0.0.rc6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/openhab/core/actions.rb +21 -9
- data/lib/openhab/core/dependency_tracking.rb +34 -0
- data/lib/openhab/core/entity_lookup.rb +132 -78
- data/lib/openhab/core/events/item_channel_link.rb +2 -2
- data/lib/openhab/core/events/item_command_event.rb +1 -1
- data/lib/openhab/core/events/item_event.rb +2 -2
- data/lib/openhab/core/events/item_state_changed_event.rb +1 -1
- data/lib/openhab/core/events/thing.rb +1 -1
- data/lib/openhab/core/items/accepted_data_types.rb +2 -2
- data/lib/openhab/core/items/contact_item.rb +1 -1
- data/lib/openhab/core/items/dimmer_item.rb +2 -2
- data/lib/openhab/core/items/generic_item.rb +45 -224
- data/lib/openhab/core/items/group_item.rb +5 -3
- data/lib/openhab/core/items/image_item.rb +2 -2
- data/lib/openhab/core/items/item.rb +219 -0
- data/lib/openhab/core/items/metadata/hash.rb +1 -1
- data/lib/openhab/core/items/metadata/namespace_hash.rb +1 -1
- data/lib/openhab/core/items/persistence.rb +19 -10
- data/lib/openhab/core/items/provider.rb +2 -2
- data/lib/openhab/core/items/proxy.rb +68 -7
- data/lib/openhab/core/items/registry.rb +6 -6
- data/lib/openhab/core/items/semantics/enumerable.rb +6 -6
- data/lib/openhab/core/items/semantics.rb +8 -7
- data/lib/openhab/core/items.rb +3 -2
- data/lib/openhab/core/provider.rb +14 -7
- data/lib/openhab/core/rules/registry.rb +2 -2
- data/lib/openhab/core/rules.rb +1 -1
- data/lib/openhab/core/script_handling.rb +6 -6
- data/lib/openhab/core/things/channel.rb +1 -1
- data/lib/openhab/core/things/channel_uid.rb +2 -2
- data/lib/openhab/core/things/item_channel_link.rb +2 -2
- data/lib/openhab/core/things/links/provider.rb +2 -2
- data/lib/openhab/core/things/profile_callback.rb +1 -1
- data/lib/openhab/core/things/registry.rb +1 -1
- data/lib/openhab/core/things/thing.rb +1 -1
- data/lib/openhab/core/timer.rb +21 -10
- data/lib/openhab/core/types/date_time_type.rb +4 -4
- data/lib/openhab/core/types/hsb_type.rb +2 -2
- data/lib/openhab/core/types/point_type.rb +1 -1
- data/lib/openhab/core/types/quantity_type.rb +1 -1
- data/lib/openhab/core/types.rb +1 -1
- data/lib/openhab/core/uid.rb +1 -1
- data/lib/openhab/core/value_cache.rb +188 -0
- data/lib/openhab/core.rb +57 -15
- data/lib/openhab/core_ext/between.rb +32 -0
- data/lib/openhab/core_ext/java/duration.rb +1 -0
- data/lib/openhab/core_ext/java/local_date.rb +1 -0
- data/lib/openhab/core_ext/java/local_time.rb +1 -0
- data/lib/openhab/core_ext/java/month.rb +12 -1
- data/lib/openhab/core_ext/java/month_day.rb +2 -0
- data/lib/openhab/core_ext/java/zoned_date_time.rb +4 -4
- data/lib/openhab/core_ext/ruby/date.rb +3 -1
- data/lib/openhab/core_ext/ruby/date_time.rb +1 -0
- data/lib/openhab/core_ext/ruby/symbol.rb +7 -0
- data/lib/openhab/core_ext/ruby/time.rb +1 -0
- data/lib/openhab/dsl/items/builder.rb +17 -10
- data/lib/openhab/dsl/items/ensure.rb +5 -5
- data/lib/openhab/dsl/items/timed_command.rb +5 -5
- data/lib/openhab/dsl/rules/automation_rule.rb +54 -40
- data/lib/openhab/dsl/rules/builder.rb +128 -79
- data/lib/openhab/dsl/rules/guard.rb +5 -5
- data/lib/openhab/dsl/rules/name_inference.rb +21 -2
- data/lib/openhab/dsl/rules/rule_triggers.rb +3 -3
- data/lib/openhab/dsl/rules/terse.rb +1 -0
- data/lib/openhab/dsl/rules/triggers/changed.rb +27 -24
- data/lib/openhab/dsl/rules/triggers/command.rb +6 -5
- data/lib/openhab/dsl/rules/triggers/conditions/duration.rb +3 -3
- data/lib/openhab/dsl/rules/triggers/cron/cron.rb +2 -2
- data/lib/openhab/dsl/rules/triggers/cron/cron_handler.rb +6 -6
- data/lib/openhab/dsl/rules/triggers/updated.rb +5 -5
- data/lib/openhab/dsl/rules/triggers/watch/watch_handler.rb +11 -12
- data/lib/openhab/dsl/things/builder.rb +73 -14
- data/lib/openhab/dsl/version.rb +2 -2
- data/lib/openhab/dsl.rb +45 -17
- data/lib/openhab/log.rb +5 -5
- data/lib/openhab/rspec/configuration.rb +5 -5
- data/lib/openhab/rspec/example_group.rb +1 -1
- data/lib/openhab/rspec/helpers.rb +5 -5
- data/lib/openhab/rspec/hooks.rb +19 -1
- data/lib/openhab/rspec/karaf.rb +13 -21
- data/lib/openhab/rspec/mocks/persistence_service.rb +15 -0
- data/lib/openhab/rspec/mocks/thing_handler.rb +2 -2
- data/lib/openhab/rspec/suspend_rules.rb +2 -1
- data/lib/openhab/yard/base_helper.rb +46 -0
- data/lib/openhab/yard/html_helper.rb +3 -3
- data/lib/openhab/yard/markdown_directive.rb +125 -0
- data/lib/openhab/yard/markdown_helper.rb +99 -0
- metadata +15 -7
@@ -0,0 +1,188 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
OpenHAB::Core.import_preset("cache")
|
4
|
+
unless defined?($sharedCache)
|
5
|
+
$sharedCache = nil
|
6
|
+
return
|
7
|
+
end
|
8
|
+
|
9
|
+
module OpenHAB
|
10
|
+
module Core
|
11
|
+
# @interface
|
12
|
+
java_import org.openhab.core.automation.module.script.rulesupport.shared.ValueCache
|
13
|
+
|
14
|
+
#
|
15
|
+
# ValueCache is the interface used to access a
|
16
|
+
# {OpenHAB::DSL.shared_cache shared cache} available between scripts and/or
|
17
|
+
# rule executions.
|
18
|
+
#
|
19
|
+
# While ValueCache looks somewhat like a Hash, it does not support
|
20
|
+
# iteration of the contained elements. So it's limited to strictly storing,
|
21
|
+
# fetching, or removing known elements.
|
22
|
+
#
|
23
|
+
# Shared caches are _not_ persisted between openHAB restarts. And in fact,
|
24
|
+
# if all scripts are unloaded that reference a particular key, that key is
|
25
|
+
# removed.
|
26
|
+
#
|
27
|
+
# @note Only the {OpenHAB::DSL.shared_cache sharedCache} is exposed in Ruby.
|
28
|
+
# For a private cache, simply use an instance variable. See
|
29
|
+
# {file:docs/ruby-basics.md#Variables Instance Variables}.
|
30
|
+
#
|
31
|
+
# @note Because every script or UI rule gets it own JRuby engine instance,
|
32
|
+
# you cannot rely on being able to access Ruby objects between them. Only
|
33
|
+
# objects that implement a Java interface that's part of Java or openHAB
|
34
|
+
# Core (such as Hash implements {java.util.Map}, or other basic
|
35
|
+
# datatypes) can be reliably stored and accessed from the shared cache.
|
36
|
+
# Likewise, you can use the cache to access data from other scripting
|
37
|
+
# languages, but they'll be all but useless in Ruby. It's best to stick
|
38
|
+
# to simple data types. If you're having troubles, serializing to_json
|
39
|
+
# before storing may help.
|
40
|
+
#
|
41
|
+
# @see https://www.openhab.org/docs/configuration/jsr223.html#cache-preset openHAB Cache Preset
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# shared_cache.compute_if_absent(:execution_count) { 0 }
|
45
|
+
# shared_cache[:execution_count] += 1
|
46
|
+
#
|
47
|
+
module ValueCache
|
48
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-5B-5D Hash#[]
|
49
|
+
def [](key)
|
50
|
+
get(key.to_s)
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Compute and store new value for key if the key is absent. This method is atomic.
|
55
|
+
#
|
56
|
+
# @param [String] key
|
57
|
+
# @yieldreturn [Object] new value
|
58
|
+
# @return [Object] new value or current value
|
59
|
+
#
|
60
|
+
def compute_if_absent(key, &block)
|
61
|
+
get(key.to_s, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-5B-5D-3D Hash#[]=
|
65
|
+
def []=(key, value)
|
66
|
+
put(key.to_s, value)
|
67
|
+
end
|
68
|
+
alias_method :store, :[]
|
69
|
+
|
70
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-delete Hash#delete
|
71
|
+
def delete(key)
|
72
|
+
key = key.to_s
|
73
|
+
if block_given?
|
74
|
+
fetch(key) do
|
75
|
+
return yield(key)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
remove(key)
|
79
|
+
end
|
80
|
+
|
81
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-fetch Hash#fetch
|
82
|
+
#
|
83
|
+
# @example
|
84
|
+
# shared_cache.fetch(:key_from_another_script) # raises NoKeyError
|
85
|
+
#
|
86
|
+
def fetch(key, *default_value)
|
87
|
+
if default_value.length > 1
|
88
|
+
raise ArgumentError,
|
89
|
+
"wrong number of arguments (given #{default_value.length + 1}, expected 0..1)"
|
90
|
+
end
|
91
|
+
|
92
|
+
key = key.to_s
|
93
|
+
if default_value.empty?
|
94
|
+
if block_given?
|
95
|
+
get(key) do
|
96
|
+
return yield(key)
|
97
|
+
end
|
98
|
+
else
|
99
|
+
get(key) do
|
100
|
+
raise KeyError.new("key not found: #{key.inspect}", key: key)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
else
|
104
|
+
get(key) { return default_value.first }
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-assoc Hash#assoc
|
109
|
+
def assoc(key)
|
110
|
+
[key, fetch(key) do
|
111
|
+
# return nil directly, without storing a value to the cache
|
112
|
+
return nil
|
113
|
+
end]
|
114
|
+
end
|
115
|
+
|
116
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-dig Hash#dig
|
117
|
+
def dig(key, *identifiers)
|
118
|
+
r = fetch(key) { return nil }
|
119
|
+
r&.dig(*identifiers)
|
120
|
+
end
|
121
|
+
|
122
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-fetch_values Hash#fetch_values
|
123
|
+
def fetch_values(*keys, &block)
|
124
|
+
result = []
|
125
|
+
keys.each do |key|
|
126
|
+
if block
|
127
|
+
result << fetch(key, &block)
|
128
|
+
else
|
129
|
+
has_value = true
|
130
|
+
value = fetch(key) { has_value = false }
|
131
|
+
result << value if has_value
|
132
|
+
end
|
133
|
+
end
|
134
|
+
result
|
135
|
+
end
|
136
|
+
|
137
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-key-3F Hash#key?
|
138
|
+
def key?(key)
|
139
|
+
!!fetch(key) { return false }
|
140
|
+
end
|
141
|
+
alias_method :has_key?, :key?
|
142
|
+
alias_method :include?, :key?
|
143
|
+
alias_method :member?, :key?
|
144
|
+
|
145
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-merge-21 Hash#merge!
|
146
|
+
def merge!(*other_hashes)
|
147
|
+
other_hashes.each do |hash|
|
148
|
+
hash.each do |(k, v)|
|
149
|
+
k = k.to_s
|
150
|
+
if block_given?
|
151
|
+
dup = true
|
152
|
+
old_value = fetch(k) do
|
153
|
+
dup = false
|
154
|
+
end
|
155
|
+
self[k] = dup ? yield(k, old_value, v) : v
|
156
|
+
else
|
157
|
+
self[k] = v
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
self
|
162
|
+
end
|
163
|
+
alias_method :update, :merge!
|
164
|
+
|
165
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-slice Hash#slice
|
166
|
+
def slice(*keys)
|
167
|
+
result = {}
|
168
|
+
keys.each do |k|
|
169
|
+
k = k.to_s
|
170
|
+
result[k] = self[k] if key?(k)
|
171
|
+
end
|
172
|
+
result
|
173
|
+
end
|
174
|
+
|
175
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-to_proc Hash#to_proc
|
176
|
+
def to_proc
|
177
|
+
@to_proc ||= ->(k) { self[k] }
|
178
|
+
end
|
179
|
+
|
180
|
+
# @see https://ruby-doc.org/core-3.1.2/Hash.html#method-i-values_at Hash#values_at
|
181
|
+
def values_at(*keys)
|
182
|
+
keys.map do |k|
|
183
|
+
self[k]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
data/lib/openhab/core.rb
CHANGED
@@ -1,21 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# several classes rely on this, so force it to load earlier
|
4
|
-
require_relative "core/provider"
|
5
|
-
|
6
|
-
Dir[File.expand_path("core/**/*.rb", __dir__)].sort.each do |f|
|
7
|
-
require f
|
8
|
-
end
|
9
|
-
|
10
3
|
module OpenHAB
|
11
|
-
# Contains classes and modules that wrap actual
|
4
|
+
# Contains classes and modules that wrap actual openHAB objects
|
12
5
|
module Core
|
13
|
-
# The
|
6
|
+
# The openHAB Version. >= 3.3.0 is required.
|
14
7
|
# @return [String]
|
15
8
|
VERSION = org.openhab.core.OpenHAB.version.freeze
|
16
9
|
|
17
10
|
unless Gem::Version.new(VERSION) >= Gem::Version.new("3.3.0")
|
18
|
-
raise "`openhab-jrubyscripting` requires
|
11
|
+
raise "`openhab-jrubyscripting` requires openHAB >= 3.3.0"
|
19
12
|
end
|
20
13
|
|
21
14
|
# @return [Integer] Number of seconds to wait between checks for automation manager
|
@@ -23,18 +16,18 @@ module OpenHAB
|
|
23
16
|
private_constant :CHECK_DELAY
|
24
17
|
class << self
|
25
18
|
#
|
26
|
-
# Wait until
|
19
|
+
# Wait until openHAB engine ready to process
|
27
20
|
#
|
28
21
|
# @return [void]
|
29
22
|
#
|
30
23
|
# @!visibility private
|
31
24
|
def wait_till_openhab_ready
|
32
|
-
logger.trace("Checking readiness of
|
25
|
+
logger.trace("Checking readiness of openHAB")
|
33
26
|
until automation_manager
|
34
27
|
logger.trace("Automation manager not loaded, checking again in #{CHECK_DELAY} seconds.")
|
35
28
|
sleep CHECK_DELAY
|
36
29
|
end
|
37
|
-
logger.trace "Automation manager instantiated,
|
30
|
+
logger.trace "Automation manager instantiated, openHAB ready for rule processing."
|
38
31
|
end
|
39
32
|
|
40
33
|
#
|
@@ -48,11 +41,60 @@ module OpenHAB
|
|
48
41
|
#
|
49
42
|
# @!attribute [r] automation_manager
|
50
43
|
# @return [org.openhab.core.automation.module.script.rulesupport.shared.ScriptedAutomationManager]
|
51
|
-
# The
|
44
|
+
# The openHAB Automation manager.
|
52
45
|
#
|
53
46
|
def automation_manager
|
54
|
-
$
|
47
|
+
$se.get("automationManager")
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Imports a specific script extension preset into the global namespace
|
52
|
+
#
|
53
|
+
# @param [String] preset
|
54
|
+
# @return [void]
|
55
|
+
#
|
56
|
+
def import_preset(preset)
|
57
|
+
import_scope_values($se.import_preset(preset))
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Imports all default script extension presets into the global namespace
|
62
|
+
#
|
63
|
+
# @!visibility private
|
64
|
+
# @return [void]
|
65
|
+
#
|
66
|
+
def import_default_presets
|
67
|
+
$se.default_presets.each { |preset| import_preset(preset) }
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Imports concrete scope values into the global namespace
|
72
|
+
#
|
73
|
+
# @param [java.util.Map<String, Object>] scope_values
|
74
|
+
# @!visibility private
|
75
|
+
# @return [void]
|
76
|
+
#
|
77
|
+
def import_scope_values(scope_values)
|
78
|
+
scope_values.for_each do |key, value|
|
79
|
+
# convert Java classes to Ruby classes
|
80
|
+
value = value.ruby_class if value.is_a?(java.lang.Class) # rubocop:disable Lint/UselessAssignment
|
81
|
+
# variables are globals; constants go into the global namespace
|
82
|
+
key = case key[0]
|
83
|
+
when "a".."z" then "$#{key}"
|
84
|
+
when "A".."Z" then "::#{key}"
|
85
|
+
end
|
86
|
+
eval("#{key} = value unless defined?(#{key})", nil, __FILE__, __LINE__) # rubocop:disable Security/Eval
|
87
|
+
end
|
55
88
|
end
|
56
89
|
end
|
90
|
+
|
91
|
+
import_default_presets
|
57
92
|
end
|
58
93
|
end
|
94
|
+
|
95
|
+
# several classes rely on this, so force it to load earlier
|
96
|
+
require_relative "core/provider"
|
97
|
+
|
98
|
+
Dir[File.expand_path("core/**/*.rb", __dir__)].sort.each do |f|
|
99
|
+
require f
|
100
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenHAB
|
4
|
+
module CoreExt
|
5
|
+
# Extensions that apply to both Date and Time classes
|
6
|
+
module Between
|
7
|
+
#
|
8
|
+
# Checks whether the the object falls between the given range.
|
9
|
+
#
|
10
|
+
# @overload between?(min, max)
|
11
|
+
# @param [Object] min The minimum value to check, inclusive
|
12
|
+
# @param [Object] max The maximum value to check, inclusive
|
13
|
+
# @return [true,false]
|
14
|
+
#
|
15
|
+
# @overload between?(range)
|
16
|
+
# @param [Range] range A range to check
|
17
|
+
# @return [true,false]
|
18
|
+
#
|
19
|
+
def between?(min, max = nil)
|
20
|
+
range = if max
|
21
|
+
Range.new(min, max, false)
|
22
|
+
else
|
23
|
+
raise ArgumentError, "Expecting a range when given a single argument" unless min.is_a?(Range)
|
24
|
+
|
25
|
+
min
|
26
|
+
end
|
27
|
+
|
28
|
+
OpenHAB::DSL.between(range).cover?(self)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -9,8 +9,19 @@ module OpenHAB
|
|
9
9
|
|
10
10
|
# Extensions to Month
|
11
11
|
class Month
|
12
|
+
include Between
|
12
13
|
# @!parse include Time
|
13
14
|
|
15
|
+
# @return [Month]
|
16
|
+
def +(other)
|
17
|
+
plus(other)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Month]
|
21
|
+
def -(other)
|
22
|
+
minus(other)
|
23
|
+
end
|
24
|
+
|
14
25
|
#
|
15
26
|
# Returns the next month
|
16
27
|
#
|
@@ -49,7 +60,7 @@ module OpenHAB
|
|
49
60
|
# during conversion. {ZonedDateTime.now} is assumed if not given.
|
50
61
|
# @return [ZonedDateTime]
|
51
62
|
def to_zoned_date_time(context = nil)
|
52
|
-
to_local_date(context).to_zoned_date_time
|
63
|
+
to_local_date(context).to_zoned_date_time(context)
|
53
64
|
end
|
54
65
|
end
|
55
66
|
end
|
@@ -10,6 +10,7 @@ module OpenHAB
|
|
10
10
|
# Extensions to ZonedDateTime
|
11
11
|
class ZonedDateTime
|
12
12
|
include Time
|
13
|
+
include Between
|
13
14
|
|
14
15
|
class << self # rubocop:disable Lint/EmptyClass
|
15
16
|
# @!attribute [r] now
|
@@ -91,11 +92,10 @@ module OpenHAB
|
|
91
92
|
# compare instants, otherwise it will differ by timezone, which we don't want
|
92
93
|
# (use eql? if you care about that)
|
93
94
|
if other.respond_to?(:to_zoned_date_time)
|
94
|
-
|
95
|
+
to_instant.compare_to(other.to_zoned_date_time(self).to_instant)
|
96
|
+
elsif other.respond_to?(:coerce) && (lhs, rhs = other.coerce(self))
|
97
|
+
lhs <=> rhs
|
95
98
|
end
|
96
|
-
return nil unless (lhs, rhs = other.coerce(self))
|
97
|
-
|
98
|
-
lhs <=> rhs
|
99
99
|
end
|
100
100
|
|
101
101
|
#
|
@@ -4,6 +4,8 @@ require "date"
|
|
4
4
|
|
5
5
|
# Extensions to Date
|
6
6
|
class Date
|
7
|
+
include OpenHAB::CoreExt::Between
|
8
|
+
|
7
9
|
#
|
8
10
|
# Extends {#+} to allow adding a {java.time.temporal.TemporalAmount TemporalAmount}
|
9
11
|
#
|
@@ -65,7 +67,7 @@ class Date
|
|
65
67
|
|
66
68
|
return self <=> other.to_date(self) if other.is_a?(java.time.MonthDay)
|
67
69
|
|
68
|
-
if other.respond_to?(:coerce) && (lhs, rhs = coerce(self))
|
70
|
+
if other.respond_to?(:coerce) && (lhs, rhs = other.coerce(self))
|
69
71
|
return lhs <=> rhs
|
70
72
|
end
|
71
73
|
|
@@ -3,36 +3,40 @@
|
|
3
3
|
module OpenHAB
|
4
4
|
module DSL
|
5
5
|
#
|
6
|
-
# Contains extensions to simplify working with
|
6
|
+
# Contains extensions to simplify working with {Item Items}.
|
7
7
|
#
|
8
8
|
module Items
|
9
|
-
# An item builder allows you to dynamically create
|
9
|
+
# An item builder allows you to dynamically create openHAB items at runtime.
|
10
10
|
# This can be useful either to create items as soon as the script loads,
|
11
11
|
# or even later based on a rule executing.
|
12
12
|
#
|
13
13
|
# @example
|
14
14
|
# items.build do
|
15
|
-
# switch_item
|
16
|
-
# switch_item
|
17
|
-
# group_item
|
18
|
-
# contact_item
|
15
|
+
# switch_item MySwitch, "My Switch"
|
16
|
+
# switch_item NotAutoupdating, autoupdate: false, channel: "mqtt:topic:1#light"
|
17
|
+
# group_item MyGroup do
|
18
|
+
# contact_item ItemInGroup, channel: "binding:thing#channel"
|
19
19
|
# end
|
20
20
|
# # passing `thing` to a group item will automatically use it as the base
|
21
21
|
# # for item channels
|
22
|
-
# group_item
|
23
|
-
# string_item
|
22
|
+
# group_item Equipment, tags: Semantics::HVAC, thing: "binding:thing"
|
23
|
+
# string_item Mode, tags: Semantics::Control, channel: "mode"
|
24
24
|
# end
|
25
25
|
# end
|
26
|
+
#
|
26
27
|
module Builder
|
27
28
|
include Core::EntityLookup
|
28
29
|
|
30
|
+
self.create_dummy_items = true
|
31
|
+
|
29
32
|
class << self
|
30
33
|
private
|
31
34
|
|
32
35
|
# @!macro def_item_method
|
33
36
|
# @!method $1_item(name, label = nil, **kwargs)
|
34
37
|
# Create a new $1 item
|
35
|
-
# @param name [String] The name for the new item
|
38
|
+
# @param name [String, Symbol, Core::Items::Proxy] The name for the new item.
|
39
|
+
# Note that you can use a string, a symbol, or even a literal constant name
|
36
40
|
# @param label [String] The item label
|
37
41
|
# @yieldparam [ItemBuilder] builder Item for further customization
|
38
42
|
# @see ItemBuilder#initialize ItemBuilder#initialize for additional arguments.
|
@@ -233,6 +237,7 @@ module OpenHAB
|
|
233
237
|
raise ArgumentError, "`name` cannot be nil" if name.nil?
|
234
238
|
raise ArgumentError, "`dimension` can only be specified with NumberItem" if dimension && type != :number
|
235
239
|
|
240
|
+
name = name.name if name.respond_to?(:name)
|
236
241
|
if provider.is_a?(GroupItemBuilder)
|
237
242
|
name = "#{provider.name_base}#{name}"
|
238
243
|
label = "#{provider.label_base}#{label}".strip if label
|
@@ -365,7 +370,7 @@ module OpenHAB
|
|
365
370
|
#
|
366
371
|
# @example
|
367
372
|
# items.build do
|
368
|
-
# date_time_item
|
373
|
+
# date_time_item Bedroom_Light_Updated do
|
369
374
|
# channel "hue:0210:1:bulb1:color", profile: "system:timestamp-update"
|
370
375
|
# end
|
371
376
|
# end
|
@@ -469,6 +474,8 @@ module OpenHAB
|
|
469
474
|
include Builder
|
470
475
|
|
471
476
|
Builder.public_instance_methods.each do |m|
|
477
|
+
next unless Builder.instance_method(m).owner == Builder
|
478
|
+
|
472
479
|
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
473
480
|
def #{m}(*args, groups: nil, **kwargs) # def dimmer_item(*args, groups: nil, **kwargs)
|
474
481
|
groups ||= [] # groups ||= []
|
@@ -7,7 +7,7 @@ module OpenHAB
|
|
7
7
|
module Items
|
8
8
|
# Functionality to implement `ensure`/`ensure_states`
|
9
9
|
module Ensure
|
10
|
-
# Contains the `ensure` method mixed into {
|
10
|
+
# Contains the `ensure` method mixed into {Item} and {GroupItem::Members}
|
11
11
|
module Ensurable
|
12
12
|
# Fluent method call that you can chain commands on to, that will
|
13
13
|
# then automatically ensure that the item is not in the command's
|
@@ -18,15 +18,15 @@ module OpenHAB
|
|
18
18
|
# @example Turn on all switches in a group that aren't already on
|
19
19
|
# MySwitchGroup.members.ensure.on
|
20
20
|
def ensure
|
21
|
-
|
21
|
+
ItemDelegate.new(self)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
# Extensions for {::
|
25
|
+
# Extensions for {::Item} to implement {Ensure}'s functionality
|
26
26
|
#
|
27
27
|
# @see OpenHAB::DSL.ensure ensure
|
28
28
|
# @see OpenHAB::DSL.ensure_states ensure_states
|
29
|
-
module
|
29
|
+
module Item
|
30
30
|
include Ensurable
|
31
31
|
|
32
32
|
Core::Items::GenericItem.prepend(self)
|
@@ -63,7 +63,7 @@ module OpenHAB
|
|
63
63
|
# "anonymous" class that wraps any method call in `ensure_states`
|
64
64
|
# before forwarding to the wrapped object
|
65
65
|
# @!visibility private
|
66
|
-
class
|
66
|
+
class ItemDelegate
|
67
67
|
def initialize(item)
|
68
68
|
@item = item
|
69
69
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module OpenHAB
|
4
4
|
module DSL
|
5
5
|
module Items
|
6
|
-
# Extensions for {
|
6
|
+
# Extensions for {Item} to implement timed commands
|
7
7
|
#
|
8
8
|
# All items have an implicit timer associated with them, enabling to
|
9
9
|
# easily set an item into a specific state for a specified duration and
|
@@ -28,7 +28,7 @@ module OpenHAB
|
|
28
28
|
# Provides information about why the expiration block of a
|
29
29
|
# {TimedCommand#command timed command} is being called.
|
30
30
|
#
|
31
|
-
# @attr [
|
31
|
+
# @attr [Item] item
|
32
32
|
# @!visibility private
|
33
33
|
# @attr [Types::Type, Proc] on_expire
|
34
34
|
# @!visibility private
|
@@ -205,13 +205,13 @@ module OpenHAB
|
|
205
205
|
#
|
206
206
|
# Execute the rule
|
207
207
|
#
|
208
|
-
# @param [Map] _mod map provided by
|
209
|
-
# @param [Map] inputs map provided by
|
208
|
+
# @param [java.util.Map] _mod map provided by openHAB rules engine
|
209
|
+
# @param [java.util.Map] inputs map provided by openHAB rules engine containing event and other information
|
210
210
|
#
|
211
211
|
def execute(_mod = nil, inputs = nil)
|
212
212
|
ThreadLocal.thread_local(**@thread_locals) do
|
213
213
|
@timed_command_details.mutex.synchronize do
|
214
|
-
logger.trace "Canceling implicit timer #{@timed_command_details.timer} for "\
|
214
|
+
logger.trace "Canceling implicit timer #{@timed_command_details.timer} for " \
|
215
215
|
"#{@timed_command_details.item.name} because received event #{inputs}"
|
216
216
|
@timed_command_details.timer.cancel
|
217
217
|
DSL.rules.remove(@timed_command_details.rule_uid)
|