Module: OpenHAB::Core::Items::Semantics

Included in:
GenericItem
Defined in:
lib/openhab/core/items/semantics.rb

Overview

Module for implementing semantics helper methods on Item in order to easily navigate the Semantic Model in your scripts. This can be extremely useful to find related items in rules that are executed for any member of a group.

Wraps org.openhab.core.model.script.actions.Semantics as well as adding a few additional convenience methods. Also includes classes for each semantic tag.

Be warned that the Semantic model is stricter than can actually be described by tags and groups on an Item. It makes assumptions that any given item only belongs to one semantic type (Location, Equipment, Point).

#Enumerable helper methods

Enumerable helper methods are also provided to complement the semantic model. These methods can be chained together to find specific item(s) based on custom tags or group memberships that are outside the semantic model.

The Enumerable helper methods apply to:

#Semantic Classes

Each Semantic Tag has a corresponding class within the org.openhab.core.semantics class hierarchy. These "semantic classes" are available as constants in the Semantics module with the corresponding name. The following table illustrates the semantic constants:

Semantic Constant openHAB's Semantic Class
Semantics::LivingRoom org.openhab.core.semantics.model.location.LivingRoom
Semantics::Lightbulb org.openhab.core.semantics.model.equipment.Lightbulb
Semantics::Control org.openhab.core.semantics.model.point.Control
Semantics::Switch org.openhab.core.semantics.model.point.Switch
Semantics::Power org.openhab.core.semantics.model.property.Power
... ...

These constants can be used as arguments to the #points, Enumerable#locations and Enumerable#equipments methods to filter their results. They can also be compared against the return value of #semantic_type, #location_type, #equipment_type, #point_type, and #property_type. They can even be used with DSL::Items::ItemBuilder#tag.

Examples:

Working with tags

# Return an array of sibling points with a "Switch" tag
Light_Color.points(Semantics::Switch)

# check semantic type
LoungeRoom_Light.equipment_type == Semantics::Lightbulb
Light_Color.property_type == Semantics::Light

switches.items

Group   gFullOn
Group   gRoomOff

Group   eGarageLights        "Garage Lights"             (lGarage)                 [ "Lightbulb" ]
Dimmer  GarageLights_Dimmer  "Garage Lights"    <light>  (eGarageLights)           [ "Switch" ]
Number  GarageLights_Scene   "Scene"                     (eGarageLights, gFullOn, gRoomOff)

Group   eMudLights           "Mud Room Lights"           (lMud)                    [ "Lightbulb" ]
Dimmer  MudLights_Dimmer     "Garage Lights"    <light>  (eMudLights)              [ "Switch" ]
Number  MudLights_Scene      "Scene"                     (eMudLights, gFullOn, gRoomOff)

Find the switch item for a scene channel on a zwave dimmer

rule "turn dimmer to full on when switch double-tapped up" do
  changed gFullOn.members, to: 1.3
  run do |event|
    dimmer_item = event.item.points(Semantics::Switch).first
    dimmer_item.ensure << 100
  end
end

Turn off all the lights in a room

rule "turn off all lights in the room when switch double-tapped down" do
  changed gRoomOff.members, to: 2.3
  run do |event|
    event
      .item
      .location
      .equipments(Semantics::Lightbulb)
      .members
      .points(Semantics::Switch)
      .ensure.off
  end
end

Finding a related item that doesn't fit in the semantic model

# We can use custom tags to identify certain items that don't quite fit in the semantic model.
# The extensions to the Enumerable mentioned above can help in this scenario.

# In the following example, the TV `Equipment` has three `Points`. However, we are using custom tags
# `Application` and `Channel` to identify the corresponding points, since the semantic model
# doesn't have a specific property for them.

# Here, we use Enumerable#tagged
# to find the point with the custom tag that we want.

# Item model:
Group   gTVPower
Group   lLivingRoom                                 [ "LivingRoom" ]

Group   eTV             "TV"       (lLivingRoom)    [ "Television" ]
Switch  TV_Power        "Power"    (eTV, gTVPower)  [ "Switch", "Power" ]
String  TV_Application  "App"      (eTV)            [ "Control", "Application" ]
String  TV_Channel      "Channel"  (eTV)            [ "Control", "Channel" ]

# Rule:
rule 'Switch TV to Netflix on startup' do
  changed gTVPower.members, to: ON
  run do |event|
    application = event.item.points.tagged('Application').first
    application << 'netflix'
  end
end

Find all semantic entities regardless of hierarchy

# All locations
items.locations

# All rooms
items.locations(Semantics::Room)

# All equipments
items.equipments

# All lightbulbs
items.equipments(Semantics::Lightbulb)

# All blinds
items.equipments(Semantics::Blinds)

# Turn off all "Power control"
items.points(Semantics::Control, Semantics::Power).off

# All items tagged "SmartLightControl"
items.tagged("SmartLightControl")

See Also:

Constant Summary collapse

Tag =

This is a marker interface for all semantic tag classes.

org.openhab.core.semantics.Tag
Location =

This is the super interface for all types that represent a Location.

org.openhab.core.semantics.Location
Equipment =

This is the super interface for all types that represent an Equipment.

org.openhab.core.semantics.Equipment
Point =

This is the super interface for all types that represent a Point.

org.openhab.core.semantics.Point
Property =

This is the super interface for all property tags.

org.openhab.core.semantics.Property

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#equipmentItem? (readonly)

Gets the related Equipment Item of this Item.

Checks ancestor groups one level at a time, returning the first Equipment Item found.

Returns:



305
306
307
# File 'lib/openhab/core/items/semantics.rb', line 305

def equipment
  Actions::Semantics.get_equipment(self)&.then(&Proxy.method(:new))
end

#equipment_typeClass? (readonly)

Returns the sub-class of Equipment related to this Item.

In other words, the #semantic_type of this Item's Equipment.

Returns:

  • (Class, nil)


318
319
320
# File 'lib/openhab/core/items/semantics.rb', line 318

def equipment_type
  Actions::Semantics.get_equipment_type(self)&.ruby_class
end

#locationItem? (readonly)

Gets the related Location Item of this Item.

Checks ancestor groups one level at a time, returning the first Location Item found.

Returns:



279
280
281
# File 'lib/openhab/core/items/semantics.rb', line 279

def location
  Actions::Semantics.get_location(self)&.then(&Proxy.method(:new))
end

#location_typeClass? (readonly)

Returns the sub-class of Location related to this Item.

In other words, the #semantic_type of this Item's Location.

Returns:

  • (Class, nil)


292
293
294
# File 'lib/openhab/core/items/semantics.rb', line 292

def location_type
  Actions::Semantics.get_location_type(self)&.ruby_class
end

#point_typeClass? (readonly)

Returns the sub-class of Point this Item is tagged with.

Returns:

  • (Class, nil)


329
330
331
# File 'lib/openhab/core/items/semantics.rb', line 329

def point_type
  Actions::Semantics.get_point_type(self)&.ruby_class
end

#property_typeClass? (readonly)

Returns the sub-class of Property this Item is tagged with.

Returns:

  • (Class, nil)


340
341
342
# File 'lib/openhab/core/items/semantics.rb', line 340

def property_type
  Actions::Semantics.get_property_type(self)&.ruby_class
end

#semantic_typeClass? (readonly)

Returns the sub-class of Tag this Item is tagged with.

It will only return the first applicable Tag, preferring a sub-class of Location, Equipment, or Point first, and if none of those are found, looks for a Property.

Returns:

  • (Class, nil)


354
355
356
# File 'lib/openhab/core/items/semantics.rb', line 354

def semantic_type
  Actions::Semantics.get_semantic_type(self)&.ruby_class
end

Instance Method Details

#equipment?true, false

Checks if this Item is an Equipment

This is implemented as checking if the item's #semantic_type is an Equipment. I.e. an Item has a single #semantic_type.

Returns:

  • (true, false)


245
246
247
# File 'lib/openhab/core/items/semantics.rb', line 245

def equipment?
  Actions::Semantics.equipment?(self)
end

#location?true, false

Checks if this Item is a Location

This is implemented as checking if the item's #semantic_type is a Location. I.e. an Item has a single #semantic_type.

Returns:

  • (true, false)


233
234
235
# File 'lib/openhab/core/items/semantics.rb', line 233

def location?
  Actions::Semantics.location?(self)
end

#point?true, false

Checks if this Item is a Point

This is implemented as checking if the item's #semantic_type is a Point. I.e. an Item has a single #semantic_type.

Returns:

  • (true, false)


256
257
258
# File 'lib/openhab/core/items/semantics.rb', line 256

def point?
  Actions::Semantics.point?(self)
end

#points(*point_or_property_types) ⇒ Array<Item>

Return the related Point Items.

Searches this Equipment Item for Points that are tagged appropriately.

If called on a Point Item, it will automatically search for sibling Points (and remove itself if found).

Examples:

Get all points for a TV

eGreatTV.points

Search an Equipment item for its switch

eGuestFan.points(Semantics::Switch) # => [GuestFan_Dimmer]

Search a Thermostat item for its current temperature item

eFamilyThermostat.points(Semantics::Status, Semantics::Temperature)
# => [FamilyThermostat_AmbTemp]

Search a Thermostat item for is setpoints

eFamilyThermostat.points(Semantics::Control, Semantics::Temperature)
# => [FamilyThermostat_HeatingSetpoint, FamilyThermostat_CoolingSetpoint]

Given a A/V receiver's input item, search for its power item

FamilyReceiver_Input.points(Semantics::Switch) # => [FamilyReceiver_Switch]

Parameters:

  • point_or_property_types (Class)

    Pass 1 or 2 classes that are sub-classes of Point or Property. Note that when comparing against semantic tags, it does a sub-class check. So if you search for [Control], you'll get items tagged with [Switch].

Returns:



385
386
387
388
389
390
391
392
# File 'lib/openhab/core/items/semantics.rb', line 385

def points(*point_or_property_types)
  return members.points(*point_or_property_types) if equipment? || location?

  # automatically search the parent equipment (or location?!) for sibling points
  result = (equipment || location)&.points(*point_or_property_types) || []
  result.delete(self)
  result
end

#semantic?true, false

Checks if this Item has any semantic tags

Returns:

  • (true, false)


265
266
267
# File 'lib/openhab/core/items/semantics.rb', line 265

def semantic?
  !!semantic_type
end