Reusable switch combination 'modes'

As my first home automation quest, I’m looking to turn my electrical radiators into ‘connected’ radiators. This to no longer depend on its time settings and limited programming capabilities, both of which I lose every time there’s a power interruption, which happens too often to my liking. Not to mention me sometimes forgetting to turn them off when there’s a disturbance in the daily/weekly schedule.

To do this, I’m going for a Shelly Plus 2PM double switch/channel device per radiator, connected to the so called ‘pilot wire’ that each radiator here has. Combined with two diodes, it allows me to switch between 4 modes depending on the switch combinations. off-off, on-on, on-off and off-on for the modes comfort, eco, no frost and off, respectively.

Because it’s a relatively simple setup, I looked at the Shelly app first to see if this can somehow be achieved without depending on some form of hub. Unfortunately, this is not the case. Their concept of scenes is on the one hand too limited and on the other hand it imposes too much configuration.

This makes Home Assistant the next preferred choice for me.
After looking at the different concepts of HA, I see ways on how to do it, but I’d like to run them by you first to make sure I’m on the right track and to overcome some issues.

I have one radiator, thus one double switch device, per room. This for five radiators for the time being, ten of them later on. Per room, I’d like to be able to select one of the four modes, which in turn perform the on-off combinations needed with the two switches.
Cycling between the modes comfort and eco needs to be done based on a daily schedule for most of the radiators, with a way to deviate from the schedule manually.

The concept of HA scenes is what appears to be fitting, with one scene per mode.
My reluctance with this idea, however, is twofold:

  1. I do not see a way to reuse the different scenes for the different devices/rooms, which would require me to define four scenes for each device
  2. Scenes do not have an on/off state. Knowing which mode is active is important, to know what temperature the radiator will be on and to possibly send a warning when I forgot to switch it off by checking the mode.

Entities (two switches in a device) have their individual state, but I constantly need the combination of the two entities.

What would be a more appropriate way to set this up?
Is there a way to reuse scenes per device that I’m overlooking?
Can the state of a scene be tracked?
Is there some way to create something like a meta entity, combining multiple entities?
Or a way to define a global device state, based on the two entities?
If either of these two options are even possible, would it allow me to switch between the different modes, making sure only one of the four is active at a given time?

I have 240v electric radiators throughout (heating only), with 110v units in the 2 baths. All but one bath has 2 or 3 wire thermostats. While I was able to replace the thermostats with Nests, I have the one that I want to make smart, similar to what you describe (just haven’t sorted that out yet).

The point in this response was about scheduling. I use Scripts to set what I want at different times of the day, and Automations to execute the scripts. (Wake, Day, Eve, Night, SleepyTime). Works very well. Unfortunately I don’t have more experience to offer more on the matter, I’m still learning HA (and interested in other suggestions you might get).

FWIW

After digging some more into all the options HA has to offer, it appears that a Template Select might be the best option to at least turn the two switches of a device into a single entity. The entity would then allow choosing from one of the four modes.

Unfortunately, as far as I can tell and based on a different discussion, a template would need to be created for each device. There’s the concept of blueprints to reuse configs with different devices, but that’s limited to generic automations and scripts.

So quite some code/config repetition can not be avoided I suppose?

Finished digging I suppose…
I’ve set HA up for testing on a spare RPi 2 and the following works nicely, be it with some minor drawbacks.

[config|homeassistent]/custom_templates/radiator_modes.jinja:

{% macro radiator_modes() %}
  {{ ['Comfort', 'Eco', 'No Frost', 'Off'] }}
{% endmacro %}

{% macro radiator_entity_prefix(device_name) -%}
  {% set switch_id = 'switch.' ~ device_name %}
  {%- set entity_prefix = switch_id ~ '_channel_' -%}
  {{ entity_prefix }}
{%- endmacro %}

{% macro radiator_mode(device_name) %}
  {% set entity_prefix = radiator_entity_prefix(device_name) %}
  {% if is_state(entity_prefix ~ '1', 'off') and is_state(entity_prefix ~ '2', 'off') %}
    {% set mode = 'Comfort' %}
  {% elif is_state(entity_prefix ~ '1', 'on') and is_state(entity_prefix ~ '2', 'on') %}
    {% set mode = 'Eco' %}
  {% elif is_state(entity_prefix ~ '1', 'off') and is_state(entity_prefix ~ '2', 'on') %}
    {% set mode = 'No Frost' %}
  {% else %}
    {% set mode = 'Off' %}
  {% endif %}
  {{ mode }}
{% endmacro %}

{% macro radiator_mode_icon(mode) %}
  {% set mapper = {
    'Comfort' : 'mdi:radiator',
    'Eco'     : 'mdi:radiator-disabled',
    'No Frost': 'mdi:snowflake-off',
    'Off'     : 'mdi:radiator-off'
  }%}
  {{ mapper.get(mode) }}
{% endmacro %}

[config|homeassistant]/templates.yaml:

- select:
  - name: "Radiator Mode"
    unique_id: 0b3b33ef-348c-4471-9534-83885e298687
    state: >
        {% from 'radiator_modes.jinja' import radiator_mode %}
        {{ radiator_mode('shellyswitch25_c8c9a367e2c4') }}
    options: >
        {% from 'radiator_modes.jinja' import radiator_modes %}
        {{ radiator_modes() }}
    select_option:
      - variables:
          entity_prefix: >
            {% from 'radiator_modes.jinja' import radiator_entity_prefix %}
            {{ radiator_entity_prefix('shellyswitch25_c8c9a367e2c4') }}
      - service: "switch.turn_{{ 'on' if option in ['Eco', 'Off'] else 'off' }}"
        target:
          entity_id: "{{ entity_prefix ~ '1' }}"
      - service: "switch.turn_{{ 'on' if option in ['Eco', 'No Frost'] else 'off' }}"
        target:
          entity_id: "{{ entity_prefix ~ '2' }}"
    icon: >
        {% from 'radiator_modes.jinja' import radiator_mode_icon %}
        {{ radiator_mode_icon(this.state) }}

The select block needs to be repeated for each device/radiator.
For each select the unique_id need to be changed, as well as the device name in two locations.
I tried transforming the sensor template into a trigger template to define a variable and see if I could reduce the need to have two locations where the device name would need to be supplied, but those variables are only initialized when the trigger is triggered.
Using the marcos works nicely to reduce code duplication, but it does require an import in each template section. It would be nice to import all macros in a global way, but I haven’t found a way to do it.