Version 5.38.0 is out
Features
- Add a default file so Gemfile doesn’t need a custom require by @jimtng in #428
This is for the upcoming support of using Gemfile and bundler for gem management.
- Support
ItemStateUpdatedEvent#last_state_update
and ItemStateChangedEvent#last_state_change
by @jimtng in #401
- Add
GenericItem#was
, #was?
, #was_xxx?
predicates, document Item#last_state
, #last_state_change
, and #last_state_update
methods by @jimtng in #397
- Support passing timer objects to other scripts via shared_cache by @jimtng in #431
- Semantic Tags: add
subclasses:
parameter to allow exact match and exclude all subclasses of the given tags by @jimtng in #433
- Support wildcard item and improve wildcard thing triggers by @jimtng in #413
Full Changelog : v5.37.0…v5.38.0
Examples:
Share timer object with other scripts (including JS)
# script1.rb:
timer = after(10.hours) { logger.warn "Timer created in script1.rb fired" }
shared_cache[:script1_timer] = timer
# inside a different JRuby UI rule or script:
# This is an openHAB timer object, not a JRuby timer object
# the reschedule method expects a ZonedDateTime
shared_cache[:script1_timer]&.reschedule(10.seconds.from_now)
# inside another JS script:
cache.shared.get("script1_timer")?.cancel()
Note that JRuby manages all the timers it created and when the script is unloaded/reloaded, all timers that were created in that script will be cancelled to avoid “runaway timers”.
openHAB does the same thing for timers in the shared cache. It will cancel it once all scripts referencing the cache have been unloaded.
If you do not want JRuby to cancel the timer upon script un/reloading, you can call Timer#unmanage.
Semantic Subclasses
# This will include CeilingFan and ExhaustFan
items.equipments(Semantics::Fan)
# This includes _only_ Fan, not the subclasses
items.equipments(Semantics::Fan, subclasses: false)
Wildcard Event Triggers
This could possibly replace having to use Group triggers if you have consistent item naming.
rule "My Rule" do
changed "LivingRoom_*_Light"
run do |event|
logger.info "#{event.item.label} changed to #{event.state}"
end
end
rule "MQTT Item Status" do
changed "mqtt:*" # Triggers on any MQTT Thing status changes
run do |event|
logger.info "Thing #{event.thing.uid} changed to #{event.thing.status}"
end
end
openHAB 5 new item properties
In openHAB 5 we have new properties for Items:
Property |
Description |
was |
The prior state before it changed to the current state. nil if it was NULL or UNDEF |
last_state_update |
The time (ZonedDateTime) when the latest state update occurred |
last_state_change |
The time (ZonedDateTime) when the latest state change occurred |
was? |
true if the prior state was not NULL or UNDEF |
was_undef? |
true if the prior state was UNDEF |
was_null? |
true if the prior state was NULL |
was_on? |
true if the prior state was ON |
was_off? |
true if the prior state was OFF |
was_open? |
true if the prior state was OPEN |
was_closed? |
true if the prior state was CLOSED |
was_up? |
true if the prior state was UP |
was_down? |
true if the prior state was DOWN |
was_playing? |
true if the prior state was PLAY |
was_paused? |
true if the prior state was PAUSE |
was_rewinding? |
true if the prior state was REWIND |
was_fast_forwarding? |
true if the prior state was FASTFORWARD |
These are in addition to the existing state
, state?
, null?
, undef?
, on?
, off?
, etc. which are used to check the current item state.
These was
predicates are also available in the ItemStateChangedEvent
, (this part isn’t new, it has been available since the beginning), and now we can check the timestamp of the change with last_state_change
, e.g.
rule "Item change rule" do
changed MyPlayerItem
run do |event|
if event.was_playing?
logger.info "MyPlayerItem was playing something, it's now #{event.state}"
end
end
end
rule "Calculate delta" do
changed MyHumidityItem
run do |event|
next unless event.was? # Make sure we have a previous state to calculate
delta = event.state - event.was
next if delta < 10 # Don't bother for small changes
logger.info "The humidity has changed by #{delta}"
logger.info "It changed to #{event.was} at #{event.last_state_change}"
end
end
rule "avoid quick on/off" do
received_command LightSwitch
run do |event|
# do not pass on the command if the light was recently changed
next if event.command != LightBulb.state && LightBulb.last_state_change > 2.seconds.ago
LightBulb.command(event.command) # Pass on the command
end
end