Energenie ENER314 RF control on Raspberry PI

I thought I’d share the basic scripts below in case they are of use to anyone new to Home Assistant and trying it get it up and running controlling the Energenie MiHome range of plugs and sockets using the ENER314 Pi-Mote control board connected to a Raspberry PI,

I’ve written these as someone new to Home Assistant, they are intended to help anyone like me who is climbing the home Assistant learning curve, so improvements and suggestions on better ways to implement it are welcome. Ideally, it would be great if someone could create a full integration for the board.

Note, these scripts work with the ENER314 Pi-Mote, which was the first model of the RF control board which supports transmit only, for use with the receive-only, control range of MiHome products. The board accepts a simple 4 bit command, mode select and a transmit enable signal from the PI. Note, these won’t work with the second model of the RF board, the ENER314-RT which uses a different set to control signals.

The ENER314 documentation states it supports 4 unique RF control channels, which devices can be trained to follow, but it appears it can support an additional 2 undocumented channels, giving 6 in total. These extra 2 channels (Channel 5 and 6) are undocumented but appear to work with the MiHome plugs, I’ve not tested them on other MiHome devices.

The following setup will need adding to your Configuration.yaml file, the first block uses the raspberry PI GPIO plugin to setup the switches (outputs) for each of the control signals required by the RF board. The second block creates 6 boolean inputs used to estimate the state of the control channels, which can only be estimated as there is no feedback from the devices.

# Configure Raspberry Pi GPIO for Energenie ENER314 RF transmitter
switch:
  - platform: rpi_gpio
    ports:
      17: EN_D0
      22: EN_D1
      23: EN_D2
      27: EN_D3
      24: EN_MODSEL
      25: EN_OUTPUT

# Define boolean inputs
input_boolean:
  en_ch1:
    name: Energenie channel 1 state
    initial: 'off'
  en_ch2:
    name: Energenie channel 2 state 
    initial: 'off'
  en_ch3:
    name: Energenie channel 3 state
    initial: 'off'
  en_ch4:
    name: Energenie channel 4 state
    initial: 'off'
  en_ch5:
    name: Energenie channel 5 state
    initial: 'off'
  en_ch6:
    name: Energenie channel 6 state
    initial: 'off'

This next block of code will need adding to your scripts.yaml file, it creates a script for switching each of the 6 channels on or off, scripts for switching All channels on or off, and a functional script (ener_transmit) which is used by the other scripts to send the commands to the RF board.

The channel scripts call the ener_transmit script, passing the data needed to send the required command and once that is completed, update the boolean input used to estimate the channel state. ener_transmit receives the command data, configures the signals to the RF board and then transmits the command to the MiHome devices (1 second transmit, 3 second wait, repeated 3 times).

ener_transmit is set to run in ‘queued’ mode, which should ensure that if multiple channel scripts are triggered at once, then Home Assistant should queue the transmit commands to ensure they are sent in sequence.

# Transmit command to Energenie
ener_transmit:
    alias: Energenie transmit command
    description: 'Transmit command'
    mode: queued             # Script is run in queued mode to ensure the commands are transmitted one at a time, in sequence, to prevent parallel script calls 
    sequence:
        - alias: Set transmitter output off           # Switch off transmitter if not already off.
          service: switch.turn_off
          data:
            entity_id: switch.en_output
        - alias: Set Modulator to ASK                 # Modulator to OOK, modulator always operates in OOK mode.
          service: switch.turn_off
          data:
            entity_id: switch.en_modsel
        - alias: Set D0                               # Set D0 pin with the state passed to it by the calling script
          service_template: "{{ d0_state }}"
          data:
            entity_id: switch.en_d0
        - alias: Set D1                               # Set D1 pin with the state passed to it by the calling script
          service_template: "{{ d1_state }}"
          data:
            entity_id: switch.en_d1
        - alias: Set D2                               # Set D2 pin with the state passed to it by the calling script
          service_template: "{{ d2_state }}"
          data:
            entity_id: switch.en_d2
        - alias: Set D3                               # Set D3 pin with the state passed to it by the calling script
          service_template: "{{ d3_state }}"
          data:
            entity_id: switch.en_d3
        - delay:                                      # Delay for command to stabilise
            seconds: 1
        # Switch on transmitter for 1 second, then wait for 3 seconds in case of RF noise, do this 3 times.
        - alias: Set transmitter output on            # Switch on transmitter.
          service: switch.turn_on
          data:
            entity_id: switch.en_output
        - delay:                                      # Transmit for 1 second
            seconds: 1
        - alias: Set transmitter output off
          service: switch.turn_off                    # Turn off transmitter
          data:
            entity_id: switch.en_output
        - delay:                                      # Wait 3 seconds before repeating
            seconds: 3 
        - alias: Set transmitter output on            # Repeat transmission
          service: switch.turn_on                     # Switch on transmitter.
          data:
            entity_id: switch.en_output
        - delay:                                      # Transmit for 1 second
            seconds: 1
        - alias: Set transmitter output off
          service: switch.turn_off                    # Turn off transmitter
          data:
            entity_id: switch.en_output
        - delay:                                      # Wait 3 seconds before repeating
            seconds: 3 
        - alias: Set transmitter output on
          service: switch.turn_on
          data:
            entity_id: switch.en_output
        - delay:                                      # Transmit for 1 second
            seconds: 1
        - alias: Set transmitter output off
          service: switch.turn_off                    # Turn off transmitter
          data:
            entity_id: switch.en_output
        - alias: Set state flag
          service_template: "{{ bool_state }}"        # Indicate the expected channel state by setting the boolean input corresponding to the channel accordingly.
          data_template:
            entity_id: "{{ bool_entity }}"
            


#*****   Energenie All Channels ON    ****
ener_all_on:
    alias: Energenie All On
    description: 'All ON'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_on'
            d1_state: 'switch.turn_on'
            d2_state: 'switch.turn_off'
            d3_state: 'switch.turn_on'
            bool_state: 'input_boolean.turn_on'
            bool_entity: 'input_boolean.en_ch1'
        - alias: Set CH2 flag
          service: input_boolean.turn_on
          data:
            entity_id: input_boolean.en_ch2
        - alias: Set CH3 flag
          service: input_boolean.turn_on
          data:
            entity_id: input_boolean.en_ch3
        - alias: Set CH4 flag
          service: input_boolean.turn_on
          data:
            entity_id: input_boolean.en_ch4
        - alias: Set CH5 flag
          service: input_boolean.turn_on
          data:
            entity_id: input_boolean.en_ch5
        - alias: Set CH6 flag
          service: input_boolean.turn_on
          data:
            entity_id: input_boolean.en_ch6

#*****   Energenie All Channels OFF    ****
ener_all_off:
    alias: Energenie All Off
    description: 'All OFF'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_on'
            d1_state: 'switch.turn_on'
            d2_state: 'switch.turn_off'
            d3_state: 'switch.turn_off'
            bool_state: 'input_boolean.turn_off'
            bool_entity: 'input_boolean.en_ch1'
        - alias: Clear CH2 flag
          service: input_boolean.turn_off
          data:
            entity_id: input_boolean.en_ch2
        - alias: Clear CH3 flag
          service: input_boolean.turn_off
          data:
            entity_id: input_boolean.en_ch3
        - alias: Clear CH4 flag
          service: input_boolean.turn_off
          data:
            entity_id: input_boolean.en_ch4
        - alias: Clear CH5 flag
          service: input_boolean.turn_off
          data:
            entity_id: input_boolean.en_ch5
        - alias: Clear CH6 flag
          service: input_boolean.turn_off
          data:
            entity_id: input_boolean.en_ch6

#*****   Energenie Channel 1 ON    ****
ener_ch1_on:
    alias: Energenie CH 1 On
    description: 'CH1 ON'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_on'
            d1_state: 'switch.turn_on'
            d2_state: 'switch.turn_on'
            d3_state: 'switch.turn_on'
            bool_state: 'input_boolean.turn_on'
            bool_entity: 'input_boolean.en_ch1'

#*****   Energenie Channel 1 OFF    ****
ener_ch1_off:
    alias: Energenie CH 1 Off
    description: 'CH1 OFF'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_on'
            d1_state: 'switch.turn_on'
            d2_state: 'switch.turn_on'
            d3_state: 'switch.turn_off'
            bool_state: 'input_boolean.turn_off'
            bool_entity: 'input_boolean.en_ch1'

#*****   Energenie Channel 2 ON    ****
ener_ch2_on:
    alias: Energenie CH 2 On
    description: 'CH2 ON'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_off'
            d1_state: 'switch.turn_on'
            d2_state: 'switch.turn_on'
            d3_state: 'switch.turn_on'
            bool_state: 'input_boolean.turn_on'
            bool_entity: 'input_boolean.en_ch2'

#*****   Energenie Channel 2 OFF    ****
ener_ch2_off:
    alias: Energenie CH 2 Off
    description: 'CH2 OFF'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_off'
            d1_state: 'switch.turn_on'
            d2_state: 'switch.turn_on'
            d3_state: 'switch.turn_off'
            bool_state: 'input_boolean.turn_off'
            bool_entity: 'input_boolean.en_ch2'
            
#*****   Energenie Channel 3 ON    ****
ener_ch3_on:
    alias: Energenie CH 3 On
    description: 'CH3 ON'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_on'
            d1_state: 'switch.turn_off'
            d2_state: 'switch.turn_on'
            d3_state: 'switch.turn_on'
            bool_state: 'input_boolean.turn_on'
            bool_entity: 'input_boolean.en_ch3'

#*****   Energenie Channel 3 OFF    ****
ener_ch3_off:
    alias: Energenie CH 3 Off
    description: 'CH3 OFF'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_on'
            d1_state: 'switch.turn_off'
            d2_state: 'switch.turn_on'
            d3_state: 'switch.turn_off'
            bool_state: 'input_boolean.turn_off'
            bool_entity: 'input_boolean.en_ch3'
            
#*****   Energenie Channel 4 ON    ****
ener_ch4_on:
    alias: Energenie CH 4 On
    description: 'CH4 ON'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_off'
            d1_state: 'switch.turn_off'
            d2_state: 'switch.turn_on'
            d3_state: 'switch.turn_on'
            bool_state: 'input_boolean.turn_on'
            bool_entity: 'input_boolean.en_ch4'

#*****   Energenie Channel 4 OFF    ****
ener_ch4_off:
    alias: Energenie CH 4 Off
    description: 'CH4 OFF'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_off'
            d1_state: 'switch.turn_off'
            d2_state: 'switch.turn_on'
            d3_state: 'switch.turn_off'
            bool_state: 'input_boolean.turn_off'
            bool_entity: 'input_boolean.en_ch4'

#**************************************************************************************
#    The following channels 5 and 6 are unofficial as they are not defined in the Energenie datasheet 
#    for the ENER314 (V1) RF Board. They use the missing signal bit combinations in the datasheet signal table, 
#    the board appears to accept them, transmit a command and MIHO002 sockets can be trained to
#    use it as a channel ID in the same way as the other channels.

#*****   Energenie Channel 5 ON    ****
ener_ch5_on:
    alias: Energenie CH 5 On
    description: 'CH5 ON'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_on'
            d1_state: 'switch.turn_off'
            d2_state: 'switch.turn_off'
            d3_state: 'switch.turn_on'
            bool_state: 'input_boolean.turn_on'
            bool_entity: 'input_boolean.en_ch5'

#*****   Energenie Channel 5 OFF    ****
ener_ch5_off:
    alias: Energenie CH 5 Off
    description: 'CH5 OFF'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_on'
            d1_state: 'switch.turn_off'
            d2_state: 'switch.turn_off'
            d3_state: 'switch.turn_off'
            bool_state: 'input_boolean.turn_off'
            bool_entity: 'input_boolean.en_ch5'
            
#*****   Energenie Channel 6 ON    ****
ener_ch6_on:
    alias: Energenie CH 6 On
    description: 'CH6 ON'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_off'
            d1_state: 'switch.turn_on'
            d2_state: 'switch.turn_off'
            d3_state: 'switch.turn_on'
            bool_state: 'input_boolean.turn_on'
            bool_entity: 'input_boolean.en_ch6'

#*****   Energenie Channel 6 OFF    ****
ener_ch6_off:
    alias: Energenie CH 6 Off
    description: 'CH6 OFF'
    sequence:
        - alias: Set command and boolean
          service: script.ener_transmit
          data:
            d0_state: 'switch.turn_off'
            d1_state: 'switch.turn_on'
            d2_state: 'switch.turn_off'
            d3_state: 'switch.turn_off'
            bool_state: 'input_boolean.turn_off'
            bool_entity: 'input_boolean.en_ch6'

3 Likes