Skip to main content Link Search Menu Expand Document (external link)

Items

Items can be directly accessed, compared, etc, without any special accessors. You may use the item name anywhere within the code and it will automatically be loaded.

Item types have methods added to them to make it flow naturally within the a ruby context. All methods of the OpenHAB item are available plus the additional methods described below.

MethodDescriptionExample
<<Sends command to itemVirtualSwitch << ON
commandalias for shovel operator («) - has optional arguments ‘for:, on_expire:’ see timed command belowVirtualSwitch.command(ON)
ensureOnly send following command/update if the item is not already in the requested stateVirtualSwitch.ensure.on
updateSends update to an itemVirtualSwitch.update(ON)
idReturns label or item name if no labellogger.info(#{item.id})
thingReturns the item’s thing. If multiple, returns first. If none, returns nil.logger.info(#{item.thing.uid})
thingsReturns an array of all things item is linked withlogger.info(#{item.things.map(&:uid)})
undef?Returns true if the state of the item is UNDEFlogger.info("SwitchTest is UNDEF") if SwitchTest.undef?
null?Returns true if the state of the item is NULLlogger.info("SwitchTest is NULL") if SwitchTest.null?
state?Returns true if the state is not UNDEF or NULLlogger.info("SwitchTest has a state") if SwitchTest.state?
stateReturns state of the item or nil if UNDEF or NULLlogger.info("SwitchTest state #{SwitchTest.state}")
to_sReturns state in string formatlogger.info(#{item.id}: #{item})
meta[]Item metadataItem1.meta['namespace'].value

state returns nil instead of UNDEF or NULL so that it can be used with with Ruby safe navigation operator &. Use undef? or null? to check for those states.

Items also support Persistence and Semantics methods.

To operate across an arbitrary collection of items you can place them in an array and execute methods against the array.

number_items = [Livingroom_Temp, Bedroom_Temp]
logger.info("Max is #{number_items.max}")
logger.info("Min is #{number_items.min}")

ensure_states

The ensure_states block may be used to across multiple objects and command/updates only sending commands when state is not in the requested state. This is useful for devices where it may be costly (such as zwave) to send commands/updates for no reason.

# VirtualSwitch is in state 'ON'
ensure_states do
  VirtualSwitch << ON       # No command will be sent
  VirtualSwitch.update(ON)  # No update will be posted
  VirtualSwitch << OFF      # Off command will be sent
  VirtualSwitch.update(OFF) # No update will be posted
end

Wrapping an entire rule or file in an ensure_states block will not ensure the states during execution of the rules.

This will not work

ensure_states do
  rule 'Items in an execution block will not have ensure_states applied to them' do
    changed VirtualSwitch
    run do 
       VirtualSwitch.on
       VirtualSwitch2.on
    end
  end
end

This will work

  rule 'ensure_states must be in an execution block' do
    changed VirtualSwitch
    run do 
       ensure_states do 
          VirtualSwitch.on
          VirtualSwitch2.on
       end
    end
  end
end

Timed commands

All items have an implicit timer associated with them, enabling to easily set an item into a specific state for a specified duration and then at the expiration of that duration have the item automatically change to another state. These timed commands are reentrant, meaning if the same timed command is triggered while an outstanding time command exist, that timed command will be rescheduled rather than creating a distinct timed command.

Timed commands are initiated by using the ‘for:’ argument with the command. This is available on both the ‘command’ method and any command methods, e.g. Switch.on.

Any update to the timed command state will result in the timer be cancelled. For example, if you have a Switch on a timer and another rule sends OFF or ON to that item the timer will be automatically canceled. Sending a different duration (for:) value for the timed command will reschedule the timed command for that new duration.

Timed command arguments

ArgumentDescriptionExample
forDuration for command to be activeSwitch.command(ON, for: 5.minutes) or Switch.on for: 5.minutes
on_expireOptional value to send as command to item when timer expiresDimmer.on for: 5.minutes, on_expire: 50
blockOptional block to invoke when timer expiresDimmer.on(for: 5.minutes) { |event| Dimmer.off if Light.on? }

If a block is provided, the on_expire argument is ignored and the block is expected to set the item into the desired state or carry out some action.

AttributeDescription
itemItem associated with timed command
commandTime command e.g. ON, OFF, etc
wasThe state of the item before the timed command
durationThe length of the timed command
on_expireValue to set the item to when the timer expires
timerThe timed command timer
expired?If the timer expired
canceled?If the timer was canceled

All Items

All items can be accessed as an enumerable using the items method.

MethodDescription
[]Get a specific item by name, this syntax can be used to dynamically load items
include?Check to see if an item with the given name exists
enumerable methodsAll methods here

Examples

Item Definition

Dimmer DimmerTest "Test Dimmer"
Switch SwitchTest "Test Switch"
logger.info("Item Count: #{items.count}")  # Item Count: 2
logger.info("Items: #{items.sort_by(&:label).map(&:label).join(', ')}")  #Items: Test Dimmer, Test Switch' 
logger.info("DimmerTest exists? #{items.include? 'DimmerTest'}") # DimmerTest exists? true
logger.info("StringTest exists? #{items.include? 'StringTest'}") # StringTest exists? false
rule 'Use dynamic item lookup to increase related dimmer brightness when switch is turned on' do
  changed SwitchTest, to: ON
  triggered { |item| items[item.name.gsub('Switch','Dimmer')].brighten(10) }
end
rule 'search for a suitable item' do
  on_start
  triggered do
    (items['DimmerTest'] || items['SwitchTest'])&.on # Send ON to DimmerTest if it exists, otherwise send it to SwitchTest
  end
end

Table of contents