Online indicator for remote controllable power plugs in openHAB
Recently I installed a number of new power sockets (like this one). The Hue bridge can not only add each switch to a light group, but also reports each plug as a Thing in openHAB. There I thought it will be a nice touch if openHAB actually reports when it sees a device plugged in. The power socket has a LED which turns on when the plug is on. The Hue bridge reports OFFLINE and ONLINE. That's useful.
The plan is to turn the LED light - and the power plug - on and off for a few second.
I have a number of power plugs, and I roll out the configuration using Ansible. Talk about creating configuration from configuration ...
Configuration
Here is an example of my "plug.yml" which holds the configuration for each plug:
---
plugs:
- { name: 'Plug ads Desktop left side', id: 'hue:0010:00513E05C343:10', var_name: 'Plug_ads_Desktop_left_side',
item_name: 'Plug_ads_Desktop_left_side', final_state: 'ON', test_plug: '1' }
- { name: 'Plug ads Desktop right side', id: 'hue:0010:00513E05C343:11', var_name: 'Plug_ads_Desktop_right_side',
item_name: 'Plug_ads_Desktop_right_side', final_state: 'ON', test_plug: '1' }
- { name: 'Plug Living Room Night', id: 'hue:0010:00513E05C343:12', var_name: 'Plug_LivingRoom_Night',
item_name: 'Plug_LivingRoom_Night_Toggle', final_state: 'ON', test_plug: '1' }
The fields in this file:
- name: just a name which is used in the Rules file
- id: the ID from the Hue bridge
- var_name: the variable name used internally in the Rules file
- item_name: the actual Item name in openHAB
- final_state: the State the Item should have once plugged in (and the online demonstration is finished)
- test_plug: "1" if the plug should show that openHAB did recognize it, otherwise no demo (just the "final_state" is set)
Rules
The Rules file is also rolled out using Ansible, and a Template. Here is the relevant Play:
- include_vars:
file: "{{ playbook_dir }}/openhab/plugs.yml"
- name: Copy Rules files
template:
src: "{{ playbook_dir }}/openhab/{{ item }}"
dest: "/etc/openhab2/rules/{{ item }}"
owner: openhab
group: openhabian
mode: 0640
with_items:
- plugs.rules
register: rules_files
The Rules template itself is split into two parts:
- Variable declarations in the top (some timers I'm using)
- Actual Rules
Variables
The variable declarations:
{% for p in plugs %}
{% if p['test_plug'] == '1' %}
var Timer timer_{{ p['var_name'] }}_2 = null
var Timer timer_{{ p['var_name'] }}_4 = null
{% endif %}
var Timer timer_{{ p['var_name'] }}_final = null
{% endfor %}
This creates three timers for openHAB. The first two are only used when the demo cycle is used, the third one sets the final state.
Rules
This demonstration is using two rules: one for when the Thing comes online, one when it goes offline.
The "Thing is online" Rule decides if the demo should run, and fires off either one or three short timers.
{% for p in plugs %}
rule "{{ p['name'] }} comes Online"
when
Thing "{{ p['id'] }}" changed from OFFLINE to ONLINE
then
logInfo("Power Plug Monitoring", "{{ p['name'] }} socket came online")
{% if p['test_plug'] == '1' %}
{{ p['item_name'] }}.sendCommand(OFF)
timer_{{ p['var_name'] }}_2 = createTimer(now.plusSeconds(2), [ |
{{ p['item_name'] }}.sendCommand(ON)
if (timer_{{ p['var_name'] }}_2 !== null) {
timer_{{ p['var_name'] }}_2.cancel()
timer_{{ p['var_name'] }}_2 = null
}
])
timer_{{ p['var_name'] }}_4 = createTimer(now.plusSeconds(4), [ |
{{ p['item_name'] }}.sendCommand(OFF)
if (timer_{{ p['var_name'] }}_4 !== null) {
timer_{{ p['var_name'] }}_4.cancel()
timer_{{ p['var_name'] }}_4 = null
}
])
timer_{{ p['var_name'] }}_final = createTimer(now.plusSeconds(6), [ |
{{ p['item_name'] }}.sendCommand({{ p['final_state'] }})
if (timer_{{ p['var_name'] }}_final !== null) {
timer_{{ p['var_name'] }}_final.cancel()
timer_{{ p['var_name'] }}_final = null
}
])
{% else %}
timer_{{ p['var_name'] }}_final = createTimer(now.plusSeconds(2), [ |
{{ p['item_name'] }}.sendCommand({{ p['final_state'] }})
if (timer_{{ p['var_name'] }}_final !== null) {
timer_{{ p['var_name'] }}_final.cancel()
timer_{{ p['var_name'] }}_final = null
}
])
{% endif %}
end
{% endfor %}
This is rolled out for each plug.
The "Thing is offline" Rule only sets the Thing back to "OFF".
{% for p in plugs %}
rule "{{ p['name'] }} goes Offline"
when
Thing "{{ p['id'] }}" changed from ONLINE to OFFLINE
then
logInfo("Power Plug Monitoring", "{{ p['name'] }} socket is offline")
{{ p['item_name'] }}.sendCommand(OFF)
end
{% endfor %}
Result/Example
Here is the entire Rule as it is deployed to openHAB, for one plug:
var Timer timer_Plug_ads_Desktop_left_side_2 = null
var Timer timer_Plug_ads_Desktop_left_side_4 = null
var Timer timer_Plug_ads_Desktop_left_side_final = null
rule "Plug ads Desktop left side comes Online"
when
Thing "hue:0010:00513E05C343:10" changed from OFFLINE to ONLINE
then
logInfo("Power Plug Monitoring", "Plug ads Desktop left side socket came online")
Plug_ads_Desktop_left_side.sendCommand(OFF)
timer_Plug_ads_Desktop_left_side_2 = createTimer(now.plusSeconds(2), [ |
Plug_ads_Desktop_left_side.sendCommand(ON)
if (timer_Plug_ads_Desktop_left_side_2 !== null) {
timer_Plug_ads_Desktop_left_side_2.cancel()
timer_Plug_ads_Desktop_left_side_2 = null
}
])
timer_Plug_ads_Desktop_left_side_4 = createTimer(now.plusSeconds(4), [ |
Plug_ads_Desktop_left_side.sendCommand(OFF)
if (timer_Plug_ads_Desktop_left_side_4 !== null) {
timer_Plug_ads_Desktop_left_side_4.cancel()
timer_Plug_ads_Desktop_left_side_4 = null
}
])
timer_Plug_ads_Desktop_left_side_final = createTimer(now.plusSeconds(6), [ |
Plug_ads_Desktop_left_side.sendCommand(ON)
if (timer_Plug_ads_Desktop_left_side_final !== null) {
timer_Plug_ads_Desktop_left_side_final.cancel()
timer_Plug_ads_Desktop_left_side_final = null
}
])
end
rule "Plug ads Desktop left side goes Offline"
when
Thing "hue:0010:00513E05C343:10" changed from ONLINE to OFFLINE
then
logInfo("Power Plug Monitoring", "Plug ads Desktop left side socket is offline")
Plug_ads_Desktop_left_side.sendCommand(OFF)
end
Comments
Display comments as Linear | Threaded