Summary
-
zigbee2mqtt
-
Rule implemented in Jruby
User interface:
- UP = turn light on
- DOWN = turn light off
- HOLD UP = gradually increase light brightness when held down
- HOLD DOWN = gradually decrease light brightness when held down
- LEFT / RIGHT = cycle through White / Various colours
- HOLD LEFT = gradually change colour temperature to cool when held down
- HOLD RIGHT = gradually change colour temperature to warm when held down
- When the increase / decrease of setting has reached its max/min value, blink the light to inform the user
- When the light is in colour mode, changing brightness or colour temperature will reset the light to white mode. This behaviour is from the light itself. No special coding to make it work this way.
Implementation:
Things file:
Thing mqtt:topic:masterbedroom-dimmer "Master Bed Room Dimmer" (mqtt:broker:mosquitto) [ availabilityTopic="zigbee/masterbedroom-dimmer/availability", payloadAvailable="online", payloadNotAvailable="offline" ] {
Channels:
Type string : action [ stateTopic="zigbee/masterbedroom-dimmer/action", commandTopic="zigbee/masterbedroom-dimmer/action/openhab-command" ]
Type number : linkquality [ stateTopic="zigbee/masterbedroom-dimmer/linkquality" ]
Type number : battery [ stateTopic="zigbee/masterbedroom-dimmer/battery" ]
}
items file:
Group gDimmers
String MasterBedRoom_Dimmer_Action (gDimmers, MasterBedRoom_Light1_Bulb) ["Control"] { channel="mqtt:topic:masterbedroom-dimmer:action" }
Number MasterBedRoom_Dimmer_Battery "Master Bed Room Dimmer Battery [%d%%]" <battery> (gBatteries) { channel="mqtt:topic:masterbedroom-dimmer:battery", expire="3h" }
Number MasterBedRoom_Dimmer_Link "Master Bed Room Dimmer Link" <network> (gSignalStrength) { channel="mqtt:topic:masterbedroom-dimmer:linkquality" }
Note: MasterBedRoom_Light1_Bulb
is the light to control - it’s an equipment
in the openhab semantic model
To augment the semantic model, a custom tag is used for the Color
item, since no such property exists in the official openhab semantic model
lightbulb items:
Group MasterBedRoom_Light1_Bulb "Master Bed Room Light1 Bulb" <light> (gMasterBedRoom, gMasterBedRoomLights) ["Lightbulb"]
Switch MasterBedRoom_Light1 "Master Bed Room Light1" <light> (MasterBedRoom_Light1_Bulb) ["Control", "Power"]
Dimmer MasterBedRoom_Light1_Dimmer "Master Bed Room Light1 Dimmer" (MasterBedRoom_Light1_Bulb) ["Control", "Light"]
Dimmer MasterBedRoom_Light1_CT "Master Bed Room Light1 CT" (MasterBedRoom_Light1_Bulb) ["Control", "ColorTemperature"]
Color MasterBedRoom_Light1_Color "Master Bed Room Light1 Color" <colorwheel> (MasterBedRoom_Light1_Bulb) ["Control", "Color"]
Rule
# frozen_string_literal: true
require 'openhab'
module ButtonAction
ON = 'on'
OFF = 'off'
BRIGHTNESS_UP = 'brightness_move_up'
BRIGHTNESS_DOWN = 'brightness_move_down'
BRIGHTNESS_STOP = 'brightness_stop'
LEFT = 'arrow_left_click'
LEFT_HOLD = 'arrow_left_hold'
LEFT_RELEASE = 'arrow_left_release'
RIGHT = 'arrow_right_click'
RIGHT_HOLD = 'arrow_right_hold'
RIGHT_RELEASE = 'arrow_right_release'
end
COLORS = {
white: '#ffffff',
red: '#ff0000',
yellow: '#FFFF00',
green: '#00FF00',
aqua: '#00FFFF',
blue: '#0000FF',
fuchsia: '#FF00FF'
}.freeze
def blink(dimmer)
power = dimmer.points(Semantics::Power).first
power.off
ensure
after(350.ms) do
power.on
end
end
@colors = Hash.new { |hash, key| hash[key] = COLORS.values }
def adjust(dimmer, delta)
return timers[dimmer]&.cancel if delta.zero?
dimmer.points(Semantics::Power).first&.ensure.on
after(0.ms, id: dimmer) do |timer|
next blink(dimmer) if (dimmer == '100 %' && delta.positive?) || (dimmer <= '1 %' && delta.negative?)
dimmer << (dimmer.to_i + delta).clamp(1, 100)
timer.reschedule 100.ms
end
end
rule 'Ikea Dimmer Handler' do
updated gDimmers.members
triggered do |action|
light = action.equipment
next unless light
dimmer = light.points(Semantics::Light).first
power = light.points(Semantics::Power).first
ct = light.points(Semantics::ColorTemperature).first
color = light.tagged('Color').first
case action.state
when ButtonAction::ON then power.ensure.on
when ButtonAction::OFF then power.ensure.off
when ButtonAction::BRIGHTNESS_UP then adjust(dimmer, 5)
when ButtonAction::BRIGHTNESS_DOWN then adjust(dimmer, -5)
when ButtonAction::BRIGHTNESS_STOP then adjust(dimmer, 0)
when ButtonAction::LEFT then color << @colors[dimmer].rotate!.first
when ButtonAction::RIGHT then color << @colors[dimmer].rotate!(-1).first
when ButtonAction::LEFT_HOLD then adjust(ct, -10)
when ButtonAction::RIGHT_HOLD then adjust(ct, 10)
when ButtonAction::RIGHT_RELEASE, ButtonAction::LEFT_RELEASE then adjust(ct, 0)
end
end
end