Online indicator for remote controllable power plugs in openHAB

Posted by ads' corner on Saturday, 2021-01-09
Posted in [Ansible][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:

1
2
3
4
5
6
7
8
9
---

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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
- 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:

  1. Variable declarations in the top (some timers I’m using)
  2. Actual Rules

Variables

The variable declarations:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{% 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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{% 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.

1
2
3
4
5
6
7
8
9
{% 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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

Categories: [Ansible] [Openhab]