Releases: openhab/openhab-jruby
Releases · openhab/openhab-jruby
v5.0.1
v5.0.0
5.0 is the first release as the officially supported gem of the openHAB organization.
Many thanks to @boc-tothefuture, @ccutrer, @jimtng, and @pacive for their work on the previous versions.
This major release contains significant restructuring by @ccutrer, with additional contributions by @jimtng.
Here is a non-exhaustive list of significant departures from the original gem:
- Logging has been reworked. There's generally no need to
include OpenHAB::Log
in your classes. {OpenHAB::Log.logger} method now
accepts a String to explicitly find whichever logger you would like, and
{OpenHAB::Logger#level=} can be used to dynamically change the log level.
Issues around the logger name while a rule is executing have also been
resolved: the top-levellogger
will be named after the file, and the
logger
within arule
or execution block will be named after the rule.
Loggers within class or instance-of-a-class context will be named after
the class. These loggers will not have their name changed simply because
their methods happened to be called while a rule is executing. Logging
also defaults to#to_s
now, instead of#inspect
. - The documentation philosophy has changed. Instead of relying on a large
set of markdown files to give both commentary and to document the details
of objects, YARD is now the primary generator
of the documentation site. Details of individual objects and methods are
now documented inline with the code, reducing duplication, aiding in
keeping them up-to-date and accurate, and being more rigorous in ensuring
the documentation has every available method listed, and in a consistent
manner. Some commentary and high level examples (such as this file) are
still maintained as dedicated markdown files, but included in the YARD
docs, instead of being a separate site that then links to the YARD docs. - The testing philosophy has also changed. The
rspec-openhab-scripting gem,
previously written as an independent project by
@ccutrer, has now been merged into this gem.
There is a tight interdependence between the two, and especially during the
large refactoring it's much easier to have them in the same repository. This
means that that gem is now the endorsed method to write tests for end-user
rules, as well as the preferred way to write tests for this gem itself, when
possible. - Major re-organization of class structures. {OpenHAB::Core} now contains any
classes that are mostly wrappers or extensions of org.openhab.core Java
classes, while {OpenHAB::DSL} contains novel Ruby-only classes that implement
a Ruby-first manner of creating rules, items, and things. - As part of the re-organization from above, the definition of a "DSL method"
that is publicly exposed and available for use has been greatly refined.
Top-level DSL methods are only available onmain
(the top-level {Object}
instance when you're writing code in a rules file and not in any other
classes), and inside of other select additional DSL constructs. If you've
written your own classes that need access to DSL methods, you either need
to explicitly call them on {OpenHAB::DSL}, or mix that module into your
class yourself. Additional internal and Java constants and methods should
no longer be leaking out of the gem's public API.
Breaking Changes
- Dropping support for openHAB < 3.4.
- The main require is now
require "openhab/dsl"
instead of just
require "openhab"
. The reason being to avoid conflicts if a gem gets
written to access openHAB via REST API. It's probably preferred that you
configure automatic requires for this file anyway. - {GenericItem} and descendants can no longer be treated as the item's state.
While convenient at times, it introduces many ambiguities on if the intention
is to interact with the item or its state, and contortionist code attempting
to support both use cases. - {OpenHAB::Core::Types::Type Enum types} no longer have implicit conversions for comparisons.
This means you can no longer doDimmerItem.state == ON
.
Predicate methods retain the implicit conversion semantics, so you can doDimmerItem.on?
.
ensure.on
, etc. also still retain their internal implicit comparisons, so you can also still doDimmerItem.ensure.on
and it will not send {ON} if the item is anything but0
.
{OpenHAB::Core::Events::ItemStateEvent} and {OpenHAB::Core::Events::ItemStateChangedEvent} both now have a full set of predicate methods to ease use from within rule execution blocks. - Semi-related to the above two points, the
#truthy?
method has been removed from any items the previously implemented it.
Instead, be more explicit on what you mean - for exampleItem.on?
.
If you would like to use a similar structure with {StringItem StringItems}, just include the ActiveSupport gem in your rules to get#blank?
and#present?
methods, and then you can useItem.state.present?
. - Semi-related to the above, the
{OpenHAB::DSL::Rules::BuilderDSL#only_if only_if} and
{OpenHAB::DSL::Rules::BuilderDSL#not_if not_if} guards now only take blocks.
This just means where you previously hadonly_if Item
you now write
only_if { Item.on? }
. - Related to the above, {OpenHAB::DSL::Rules::BuilderDSL#changed changed for:}
guards no longer take items. This just means if you previously had
changed Item, for: OtherItem
you now write
changed Item, for: -> { OtherItem.state }
. - {QuantityType} is no longer implicitly
convertible and comparable against Strings. Use the|
operator for easy
construction of {QuantityType}s:10 | "°F"
. - {HSBType} is no longer convertible and comparable against Strings, Hashes,
and Arrays. Just construct an HSBType. Sending a HTML hex color as a string
as a command is still supported. - {PointType} is no longer convertible and comparable against Strings and
Hashes. Just construct a PointType. Send strings as a command is still supported. - {QuantityType} can no longer be compared against
Numeric
or {DecimalType} outside
a {OpenHAB::DSL.unit unit} block. Either compare it against another QuantityType, or
convert it with to_f first, perform the comparison inside a
{OpenHAB::DSL.unit unit} block, or {OpenHAB::DSL.unit! permanently set} your
preferred units. - The top-level
groups
method providing access to only {GroupItem}s has been
removed. Useitems.grep(GroupItem)
if you would like to filter to only
groups. GenericItem#id
no longer exists; just use
{Item#to_s Item#to_s} which does what#id
used to do.states?(*items)
helper is gone. Just useitems.all?(:state?)
, or in
the rare cased you usedstates?(*items, things: true)
, use
items.all? { |i| i.state? && i.things.all?(&:online?) }
.- {GroupItem} is no longer {Enumerable}, and you must use
{GroupItem#members GroupItem#members}. - {GroupItem#all_members GroupItem#all_members} no
longer has afilter
parameter; usegrep
if you want just {GroupItem}s. create_timer
no longer exists as an alias for {after}.Item#meta
is no longer a supported alias for
{Item#metadata Item#metadata}.- Triggers (such as {OpenHAB::DSL::Rules::BuilderDSL#changed changed},
{OpenHAB::DSL::Rules::BuilderDSL#updated updated}, and
{OpenHAB::DSL::Rules::BuilderDSL#received_command received_command} that
previously took a splat or an Array of Items now only take a splat.
This just means instead ofchanged [Item1, Item2]
you write
changed Item1, Item2
, or if you have an actual array you write
changed(*item_array)
. This greatly simplifies the internal code that has to
distinguish between {GroupItem::Members GroupItem::Members} and other
types of collections of items. - Date and time objects have been reworked:
TimeOfDay
has been replaced with {LocalTime}- Date/time objects are no longer comparable to strings.
Please use the correct type. - Comparisons among the varying date/time classes all work.
- See also Working With Time
- Persistence methods no longer accept a {Duration}. Please use
Duration#ago
instead.
- Thing actions are no longer available as a top level method. You must use the
{OpenHAB::Core::Things::Thing#actions Thing} object. - Thing actions whose scope does not match the thing's binding are no longer
directly available on {OpenHAB::Core::Things::Thing Thing}; you must
explicitly access them via
{OpenHAB::Core::Things::Thing#actions Thing#actions}. - {OpenHAB::Core::Items::Persistence Persistence} predicates are no longer
aliased without the?
(i.e. you must call#changed_since?
, not
#changed_since
). - Timers with IDs are no longer uniqueified by where they were created. Make
sure you're using a completely unique timer ID if you're using them in
multiple locations. For example,
after(1.minute, id: [:this_logical_usage, event.item])
. This makes it
possible to schedule the same logically re-entrant timer from multiple rules. OpenHAB.conf_root
was renamed to {OpenHAB::Core.config_folder}.- {OpenHAB::Core::Items::GenericItem#metadata Metadata} now defaults to using transient backing provider.
This means that if you add metadata to an item from Ruby, it will disappear when the script is unloaded.
See {OpenHAB::DSL.provider} for how to revert to the old behavior within a single block, or for your entire script. - {OpenHAB::Core::Items::GenericItem#metadata Metadata} will now be serialized before being set.
This fixes a complicated issue where types would changed unexpectedly, or even worse, reference Ruby classes that are not even available in the current JRuby inst...