Module: OpenHAB::DSL
- Includes:
- Core::Actions, Core::EntityLookup, Core::ScriptHandling, Rules::Terse
- Included in:
- Rules::BuilderDSL
- Defined in:
- lib/openhab/dsl.rb,
lib/openhab/dsl/rules.rb,
lib/openhab/dsl/events.rb,
lib/openhab/dsl/version.rb,
lib/openhab/dsl/debouncer.rb,
lib/openhab/dsl/items/tags.rb,
lib/openhab/dsl/rules/guard.rb,
lib/openhab/dsl/rules/terse.rb,
lib/openhab/dsl/items/ensure.rb,
lib/openhab/dsl/thread_local.rb,
lib/openhab/dsl/items/builder.rb,
lib/openhab/dsl/rules/builder.rb,
lib/openhab/dsl/timer_manager.rb,
lib/openhab/dsl/rules/property.rb,
lib/openhab/dsl/rules/triggers.rb,
lib/openhab/dsl/things/builder.rb,
lib/openhab/dsl/sitemaps/builder.rb,
lib/openhab/dsl/events/watch_event.rb,
lib/openhab/dsl/items/timed_command.rb,
lib/openhab/dsl/rules/rule_triggers.rb,
lib/openhab/dsl/rules/name_inference.rb,
lib/openhab/dsl/rules/automation_rule.rb,
lib/openhab/dsl/rules/triggers/changed.rb,
lib/openhab/dsl/rules/triggers/channel.rb,
lib/openhab/dsl/rules/triggers/command.rb,
lib/openhab/dsl/rules/triggers/trigger.rb,
lib/openhab/dsl/rules/triggers/updated.rb,
lib/openhab/dsl/rules/triggers/cron/cron.rb,
lib/openhab/dsl/rules/triggers/conditions.rb,
lib/openhab/dsl/config_description/builder.rb,
lib/openhab/dsl/rules/triggers/conditions/generic.rb,
lib/openhab/dsl/rules/triggers/conditions/duration.rb,
lib/openhab/dsl/rules/triggers/watch/watch_handler.rb
Overview
The main DSL available to rules.
Methods on this module are extended onto main
, the top level self
in
any file. You can also access them as class methods on the module for use
inside of other classes, or include the module.
Defined Under Namespace
Modules: ConfigDescription, Events, Items, Rules, Sitemaps, Things Classes: Debouncer, TimerManager
Constant Summary collapse
- VERSION =
Version of openHAB helper libraries
"5.39.0"
Rule Creation collapse
-
.rule(name = nil, id: nil, **kwargs) {|rule| ... } ⇒ Core::Rules::Rule?
Create a new rule.
-
.rule!(name = nil, id: nil, **kwargs, &block) ⇒ Object
Creates a rule that will remove existing rules with the same id, even when the id has been inferred.
-
.scene(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs) { ... } ⇒ Core::Rules::Rule?
Create a new scene.
-
.scene!(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block) ⇒ Object
Creates a scene that will remove existing rules/scenes with the same id, even when the id has been inferred.
-
.script(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs) { ... } ⇒ Core::Rules::Rule?
Create a new script.
-
.script!(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block) ⇒ Object
Creates a script that will remove existing rules/scripts with the same id, even when the id has been inferred.
Rule Support collapse
-
.config_description(uri = nil) { ... } ⇒ org.openhab.core.config.core.ConfigDescription
Create a ConfigDescription object.
-
.profile(id, label: nil, type: :state, config_description: nil) {|event, command: nil, state: nil, trigger: nil, time_series: nil, callback:, link:, item:, channel_uid:, configuration:, context:| ... } ⇒ void
Defines a new profile that can be applied to item channel links.
Object Access collapse
-
.items ⇒ Core::Items::Registry
Fetches all items from the item registry.
-
.rules ⇒ Core::Rules::Registry
Fetches all rules from the rule registry.
-
.shared_cache ⇒ Core::ValueCache
ValueCache is the interface used to access a shared cache available between scripts and/or rule executions.
- .sitemaps ⇒ Core::Sitemaps::Provider
-
.things ⇒ Core::Things::Registry
Get all things known to openHAB.
-
.timers ⇒ TimerManager
Provides access to timers created by after.
Utilities collapse
-
.after(duration, id: nil, reschedule: true) {|timer| ... } ⇒ Core::Timer
Create a timer and execute the supplied block after the specified duration.
-
.between(range) ⇒ Range
Convert a string based range into a range of LocalTime, LocalDate, MonthDay, or ZonedDateTime depending on the format of the string.
-
.debounce_for(debounce_time, id: nil, &block) ⇒ void
Waits until calls to this method have stopped firing for a period of time before executing the block.
-
.only_every(interval, id: nil, &block) ⇒ void
Limit how often the given block executes to the specified interval.
-
.store_states(*items) ⇒ Core::Items::StateStorage
Store states of supplied items.
-
.throttle_for(duration, id: nil, &block) ⇒ void
Rate-limits block executions by delaying calls and only executing the last call within the given duration.
-
.transform(type, function, value) ⇒ String
Applies a transformation of a given type with some function to a value.
Block Modifiers collapse
These methods allow certain operations to be grouped inside the given block to reduce repetitions
-
.ensure_states { ... } ⇒ Object
Global method that takes a block and for the duration of the block all commands sent will check if the item is in the command's state before sending the command.
-
.ensure_states!(active: true) ⇒ Boolean
Permanently enable conditional execution of commands and updates for the current thread.
- .holiday_file(*args) ⇒ Object
-
.holiday_file!(file = nil) ⇒ Symbol?
Sets a thread local variable to set the default holiday file.
-
.persistence(service) { ... } ⇒ Object
Sets a thread local variable to set the default persistence service for method calls inside the block.
-
.persistence!(service = nil) ⇒ Object?
Permanently sets the default persistence service for the current thread.
-
.provider(*providers, **providers_by_type) { ... } ⇒ Object
Sets the implicit provider(s) for operations inside the block.
-
.provider!(things: nil, items: nil, metadata: nil, links: nil, **metadata_items) ⇒ Hash
Permanently set the implicit provider(s) for this thread.
-
.unit(*units) { ... } ⇒ Object
Sets the implicit unit(s) for operations inside the block.
-
.unit!(*units) ⇒ Hash<javax.measure.Dimension=>javax.measure.Unit>
Permanently sets the implicit unit(s) for this thread.
Methods included from Rules::Terse
#changed, #channel, #channel_linked, #channel_unlinked, #cron, #every, #item_added, #item_removed, #item_updated, #on_start, #received_command, #thing_added, #thing_removed, #thing_updated, #updated
Methods included from Core::ScriptHandling
script_loaded, script_unloaded
Methods included from Core::Actions
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object (private)
Provide access to the script context / variables see OpenHAB::DSL::Rules::AutomationRule#execute!
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 |
# File 'lib/openhab/dsl.rb', line 1112 def method_missing(method, *args) return super unless args.empty? && !block_given? if (context = Thread.current[:openhab_context]) && context.key?(method) logger.trace { "DSL#method_missing found context variable: '#{method}'" } return context[method] elsif Core.ui_context&.key?(method) logger.trace { "DSL#method_missing found UI context variable: '#{method}'" } return Core.ui_context[method] end super end |
Class Method Details
.after(duration, id: nil, reschedule: true) {|timer| ... } ⇒ Core::Timer
Create a timer and execute the supplied block after the specified duration
Reentrant Timers
Timers with an id are reentrant by id. Reentrant means that when the same id is encountered, the timer is rescheduled rather than creating a second new timer. Note that the timer will execute the block provided in the latest call.
This removes the need for the usual boilerplate code to manually keep track of timer objects.
Timers with id
can be managed with the built-in timers object.
When a timer is cancelled, it will be removed from the object.
Be sure that your ids are unique. For example, if you're using items as your
ids, you either need to be sure you don't use the same item for multiple logical contexts,
or you need to make your id more specific, by doing something like embedding the item in
array with a symbol of the timer's purpose, like [:vacancy, item]
. But also note that
assuming default settings, every Ruby file (for file-based rules) or UI rule gets its
own instance of the timers object, so you don't need to worry about collisions among
different files.
Sharing Timers with other scripts
When a timer is stored in the shared_cache, it will automatically be converted into an openHAB Timer object. It can then be used in other scripts or UI rules, written in JRuby or other supported languages.
Timers are normally managed by TimerManager, and are normally automatically cancelled when the script unloads/reloads. To disable this automatic timer cancellation at script unload, call Core::Timer#unmanage.
openHAB will cancel the timer stored in the shared_cache and remove the cache entry when all the scripts that had accessed it have been unloaded.
433 434 435 436 437 438 439 |
# File 'lib/openhab/dsl.rb', line 433 def after(duration, id: nil, reschedule: true, &block) raise ArgumentError, "Block is required" unless block # Carry rule name to timer thread_locals = ThreadLocal.persist timers.create(duration, id:, reschedule:, thread_locals:, block:) end |
.between(range) ⇒ Range
Convert a string based range into a range of LocalTime, LocalDate, MonthDay, or ZonedDateTime depending on the format of the string.
463 464 465 466 467 468 469 |
# File 'lib/openhab/dsl.rb', line 463 def between(range) raise ArgumentError, "Supplied object must be a range" unless range.is_a?(Range) start = try_parse_time_like(range.begin) finish = try_parse_time_like(range.end) Range.new(start, finish, range.exclude_end?) end |
.config_description(uri = nil) { ... } ⇒ org.openhab.core.config.core.ConfigDescription
Create a ConfigDescription object.
251 252 253 254 255 |
# File 'lib/openhab/dsl.rb', line 251 def config_description(uri = nil, &block) raise ArgumentError, "Block is required" unless block ConfigDescription::Builder.new.build(uri, &block) end |
.debounce_for(debounce_time, id: nil, &block) ⇒ void
This method returns an undefined value.
Waits until calls to this method have stopped firing for a period of time before executing the block.
This method acts as a guard for the given block to ensure that it doesn't get executed
too frequently. The debounce_for method can be called as frequently as possible.
The given block, however, will only be executed once the debounce_time
has passed
since the last call to debounce_for.
This method can be used from within a UI rule as well as from a file-based rule.
535 536 537 538 |
# File 'lib/openhab/dsl.rb', line 535 def debounce_for(debounce_time, id: nil, &block) idle_time = debounce_time.is_a?(Range) ? debounce_time.begin : debounce_time debounce(for: debounce_time, idle_time:, id:, &block) end |
.ensure_states { ... } ⇒ Object
Global method that takes a block and for the duration of the block all commands sent will check if the item is in the command's state before sending the command. This also applies to updates.
723 724 725 726 727 728 |
# File 'lib/openhab/dsl.rb', line 723 def ensure_states old = ensure_states! yield ensure ensure_states!(active: old) end |
.ensure_states!(active: true) ⇒ Boolean
This method is only intended for use at the top level of rule scripts. If it's used within library methods, or hap-hazardly within rules, things can get very confusing because the prior state won't be properly restored.
Permanently enable conditional execution of commands and updates for the current thread.
When conditional executions are enabled, commands and updates will only be sent if the item's current state is not the same as the command or updated state. This eliminates the need to chain the command and update calls through ensure.
When conditional executions are enabled either by this method or within a block of ensure_states,
commands and updates can still be forcefully executed using the corresponding bang methods, e.g.
Item1.on!
, Item1.command!(50)
, or Item1.update!(ON)
.
672 673 674 675 676 |
# File 'lib/openhab/dsl.rb', line 672 def ensure_states!(active: true) old = Thread.current[:openhab_ensure_states] Thread.current[:openhab_ensure_states] = active old end |
.holiday_file(file) { ... } ⇒ Object .holiday_file ⇒ String?
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 |
# File 'lib/openhab/dsl.rb', line 1053 def holiday_file(*args) raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 0..1)" if args.length > 1 old = Thread.current[:openhab_holiday_file] return old if args.empty? holiday_file!(args.first) yield ensure holiday_file!(old) end |
.holiday_file!(file = nil) ⇒ Symbol?
Sets a thread local variable to set the default holiday file.
1078 1079 1080 |
# File 'lib/openhab/dsl.rb', line 1078 def holiday_file!(file = nil) Thread.current[:openhab_holiday_file] = file end |
.items ⇒ Core::Items::Registry
Fetches all items from the item registry
The examples all assume the following items exist.
Dimmer DimmerTest "Test Dimmer"
Switch SwitchTest "Test Switch"
2 |
# File 'lib/openhab/dsl.rb', line 2 def items; end |
.only_every(interval, id: nil, &block) ⇒ void
This method returns an undefined value.
Limit how often the given block executes to the specified interval.
only_every will execute the given block but prevents further executions until the given interval has passed. In contrast, throttle_for will not execute the block immediately, and will wait until the end of the interval.
598 599 600 601 |
# File 'lib/openhab/dsl.rb', line 598 def only_every(interval, id: nil, &block) interval = 1.send(interval) if %i[second minute hour day].include?(interval) debounce(for: interval, leading: true, id:, &block) end |
.persistence(service) { ... } ⇒ Object
Sets a thread local variable to set the default persistence service for method calls inside the block
748 749 750 751 752 753 |
# File 'lib/openhab/dsl.rb', line 748 def persistence(service) old = persistence!(service) yield ensure persistence!(old) end |
.persistence!(service = nil) ⇒ Object?
This method is only intended for use at the top level of rule scripts. If it's used within library methods, or hap-hazardly within rules, things can get very confusing because the prior state won't be properly restored.
Permanently sets the default persistence service for the current thread
770 771 772 773 774 |
# File 'lib/openhab/dsl.rb', line 770 def persistence!(service = nil) old = Thread.current[:openhab_persistence_service] Thread.current[:openhab_persistence_service] = service old end |
.profile(id, label: nil, type: :state, config_description: nil) {|event, command: nil, state: nil, trigger: nil, time_series: nil, callback:, link:, item:, channel_uid:, configuration:, context:| ... } ⇒ void
This method returns an undefined value.
Defines a new profile that can be applied to item channel links.
To create a profile that can be used in the UI, provide a label and optionally a config_description, otherwise the profile will not be visible in the UI.
221 222 223 224 225 226 227 228 229 |
# File 'lib/openhab/dsl.rb', line 221 def profile(id, label: nil, type: :state, config_description: nil, &block) raise ArgumentError, "Block is required" unless block id = id.to_s ThreadLocal.thread_local(openhab_rule_type: "profile", openhab_rule_uid: id) do Core::ProfileFactory.instance.register(id, block, label:, type:, config_description:) end end |
.provider(*providers, **providers_by_type) { ... } ⇒ Object
Sets the implicit provider(s) for operations inside the block.
924 925 926 927 928 929 930 931 932 933 |
# File 'lib/openhab/dsl.rb', line 924 def provider(*providers, **providers_by_type) raise ArgumentError, "You must give a block to set the provider for the duration of" unless block_given? begin old_providers = provider!(*providers, **providers_by_type) yield ensure Thread.current[:openhab_providers] = old_providers end end |
.provider!(things: nil, items: nil, metadata: nil, links: nil, **metadata_items) ⇒ Hash
This method is only intended for use at the top level of rule scripts. If it's used within library methods, or hap-hazardly within rules, things can get very confusing because the prior state won't be properly restored.
Permanently set the implicit provider(s) for this thread.
provider! calls are cumulative - additional calls will not erase the effects of previous calls unless they are for the same provider type.
966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 |
# File 'lib/openhab/dsl.rb', line 966 def provider!(*providers, **providers_by_type) thread_providers = Thread.current[:openhab_providers] ||= {} old_providers = thread_providers.dup providers.each do |provider| case provider when Core::Provider thread_providers[provider.class.type] = provider when org.openhab.core.common.registry.ManagedProvider type = provider.type unless type raise ArgumentError, "#{provider.inspect} is for objects which are not supported by openhab-scripting" end thread_providers[type] = provider when Proc, :transient, :persistent Core::Provider::KNOWN_TYPES.each do |known_type| thread_providers[known_type] = provider end when Hash # non-symbols can't be used as kwargs, so Item keys show up as a separate hash here # just merge it in, and allow it to be handled below providers_by_type.merge!(provider) else raise ArgumentError, "#{provider.inspect} is not a valid provider" end end providers_by_type.each do |type, provider| case provider when Proc, org.openhab.core.common.registry.ManagedProvider, :transient, :persistent, nil nil else raise ArgumentError, "#{provider.inspect} is not a valid provider" end case type when :items, :metadata, :things, :links if provider.is_a?(org.openhab.core.common.registry.ManagedProvider) && provider.type != type raise ArgumentError, "#{provider.inspect} is not a provider for #{type}" end thread_providers[type] = provider when Symbol, String (thread_providers[:metadata_namespaces] ||= {})[type.to_s] = provider when Item (thread_providers[:metadata_items] ||= {})[type.name] = provider else raise ArgumentError, "#{type.inspect} is not provider type" end end old_providers end |
.rule(name = nil, id: nil, **kwargs) {|rule| ... } ⇒ Core::Rules::Rule?
Create a new rule
The rule must have at least one trigger and one execution block. To create a "script" without any triggers, use script.
When explicit id
is not provided, the rule's ID will be inferred from the block's source location,
and a suffix will be added to avoid clashing against existing rules.
When an explicit id
is provided and an existing rule with the same id already exists,
the rule will not be created, and the method will return nil.
To ensure that a rule is created even when the same id already exists, use rule! or call rules.remove to remove any existing rule prior to creating the new rule.
87 88 89 |
# File 'lib/openhab/dsl.rb', line 87 def rule(name = nil, id: nil, **kwargs, &block) rules.build { rule(name, id:, **kwargs, &block) } end |
.rule!(name = nil, id: nil, **kwargs, &block) ⇒ Object
Creates a rule that will remove existing rules with the same id, even when the id has been inferred.
93 94 95 |
# File 'lib/openhab/dsl.rb', line 93 def rule!(name = nil, id: nil, **kwargs, &block) rules.build { rule(name, id:, replace: true, **kwargs, &block) } end |
.rules ⇒ Core::Rules::Registry
Fetches all rules from the rule registry.
284 285 286 |
# File 'lib/openhab/dsl.rb', line 284 def rules Core::Rules::Registry.instance end |
.scene(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs) { ... } ⇒ Core::Rules::Rule?
Create a new scene
A scene is a rule with no triggers. It can be called by various other actions, such as the Run Rules action.
98 99 100 |
# File 'lib/openhab/dsl.rb', line 98 def scene(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block) rules.build { scene(name, description:, id:, tag:, tags:, **kwargs, &block) } end |
.scene!(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block) ⇒ Object
Creates a scene that will remove existing rules/scenes with the same id, even when the id has been inferred.
104 105 106 107 108 |
# File 'lib/openhab/dsl.rb', line 104 def scene!(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block) rules.build do scene(name, description:, id:, tag:, tags:, replace: true, **kwargs, &block) end end |
.script(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs) { ... } ⇒ Core::Rules::Rule?
Create a new script
A script is a rule with no triggers. It can be called by various other actions, such as the Run Rules action, or by calling Core::Rules::Rule#trigger.
Scripts can be executed with some additional context, similar to method parameters (see Core::Rules::Rule#trigger). The context can be accessed from within the script's execution block as a "local" variable.
111 112 113 |
# File 'lib/openhab/dsl.rb', line 111 def script(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block) rules.build { script(name, description:, id:, tag:, tags:, **kwargs, &block) } end |
.script!(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block) ⇒ Object
Creates a script that will remove existing rules/scripts with the same id, even when the id has been inferred.
117 118 119 120 121 |
# File 'lib/openhab/dsl.rb', line 117 def script!(name = nil, description: nil, id: nil, tag: nil, tags: nil, **kwargs, &block) rules.build do script(name, description:, id:, tag:, tags:, replace: true, **kwargs, &block) end end |
.shared_cache ⇒ Core::ValueCache
Only the sharedCache is exposed in Ruby. For a private cache, simply use an instance variable. See Instance Variables.
Because every script or UI rule gets its own JRuby engine instance, you cannot rely on being able to access Ruby objects between them. Only objects that implement a Java interface that's part of Java or openHAB Core (such as Hash implements java.util.Map, or other basic datatypes) can be reliably stored and accessed from the shared cache. Likewise, you can use the cache to access data from other scripting languages, but they'll be all but useless in Ruby. It's best to stick to simple data types. If you're having troubles, serializing to_json before storing may help.
ValueCache is the interface used to access a shared cache available between scripts and/or rule executions.
While ValueCache looks somewhat like a Hash, it does not support iteration of the contained elements. So it's limited to strictly storing, fetching, or removing known elements.
Shared caches are not persisted between openHAB restarts. And in fact, if all scripts are unloaded that reference a particular key, that key is removed.
275 276 277 |
# File 'lib/openhab/dsl.rb', line 275 def shared_cache $sharedCache end |
.sitemaps ⇒ Core::Sitemaps::Provider
289 290 291 |
# File 'lib/openhab/dsl.rb', line 289 def sitemaps Core::Sitemaps::Provider.instance end |
.store_states(*items) ⇒ Core::Items::StateStorage
Store states of supplied items
Takes one or more items and returns a map {Item => State}
with the
current state of each item. It is implemented by calling openHAB's
events.storeStates().
624 625 626 627 628 629 630 631 |
# File 'lib/openhab/dsl.rb', line 624 def store_states(*items) states = Core::Items::StateStorage.from_items(*items) if block_given? yield states.restore end states end |
.things ⇒ Core::Things::Registry
Get all things known to openHAB
5 |
# File 'lib/openhab/dsl.rb', line 5 def things; end |
.throttle_for(duration, id: nil, &block) ⇒ void
This method returns an undefined value.
Rate-limits block executions by delaying calls and only executing the last call within the given duration.
When throttle_for is called, it will hold from executing the block and start a fixed timer for the given duration. Should more calls occur during this time, keep holding and once the wait time is over, execute the block.
throttle_for will execute the block after it had waited for the given duration,
regardless of how frequently throttle_for
was called.
In contrast, debounce_for will wait until there is a minimum interval
between two triggers.
throttle_for is ideal in situations where regular status updates need to be made for frequently changing values. It is also useful when a rule responds to triggers from multiple related items that are updated at around the same time. Instead of executing the rule multiple times, throttle_for will wait for a pre-set amount of time since the first group of triggers occurred before executing the rule.
568 569 570 |
# File 'lib/openhab/dsl.rb', line 568 def throttle_for(duration, id: nil, &block) debounce(for: duration, id:, &block) end |
.timers ⇒ TimerManager
Provides access to timers created by after
297 298 299 |
# File 'lib/openhab/dsl.rb', line 297 def timers TimerManager.instance end |
.transform(type, function, value) ⇒ String
Applies a transformation of a given type with some function to a value.
573 574 575 |
# File 'lib/openhab/dsl.rb', line 573 def transform(type, function, value) Transformation.transform(type, function, value) end |
.unit(*units) { ... } ⇒ Object .unit(dimension) ⇒ javax.measure.Unit
Sets the implicit unit(s) for operations inside the block.
837 838 839 840 841 842 843 844 845 846 847 848 849 850 |
# File 'lib/openhab/dsl.rb', line 837 def unit(*units) if units.length == 1 && units.first.is_a?(javax.measure.Dimension) return Thread.current[:openhab_units]&.[](units.first) end raise ArgumentError, "You must give a block to set the unit for the duration of" unless block_given? begin old_units = unit!(*units) yield ensure Thread.current[:openhab_units] = old_units end end |
.unit!(*units) ⇒ Hash<javax.measure.Dimension=>javax.measure.Unit> .unit! ⇒ Hash<javax.measure.Dimension=>javax.measure.Unit>
This method is only intended for use at the top level of rule scripts. If it's used within library methods, or hap-hazardly within rules, things can get very confusing because the prior state won't be properly restored.
Permanently sets the implicit unit(s) for this thread
unit! calls are cumulative - additional calls will not erase the effects of previous calls unless they are for the same dimension.
893 894 895 896 897 898 899 900 901 902 |
# File 'lib/openhab/dsl.rb', line 893 def unit!(*units) units = units.each_with_object({}) do |unit, r| unit = org.openhab.core.types.util.UnitUtils.parse_unit(unit) if unit.is_a?(String) r[unit.dimension] = unit end old_units = Thread.current[:openhab_units] || {} Thread.current[:openhab_units] = units.empty? ? {} : old_units.merge(units) old_units end |