This project has been made with the help of Tam and Gérard/F6EEQ.
Prior to Zigbee adoption, Profalux roller shutter / remote communications were relying on a 868MHz protocol using rolling codes.
The most common remote, usually shipped with roller shutter, is a 3 buttons MAI-EMPX-B1
model.
Such shutters can be controlled by several remotes, each remote can be paired to several shutters. See this document (in french) for pairing a new remote to an already paired couple of roller shutter / remote.
With the help of a Flipper Zero, each of the 3 commands sent by the remote to the shutter when pressing up
/ down
/ stop
can be easily captured but replaying these commands is also not an option since commands contain rolling codes protecting shutters from replay attacks.
So, the best option remains to emulate button press with a micro-controller connected to the remote.
To get Home Assitant being able to control roller shutters, remote integration to EspHome / HA is performed through 2 main steps:
- connect the remote to an ESP8266 micro-controller to emulate button press actions
- setting up an EspHome device exposing buttons, and integrate it to HA if needed.
N.B. the idea is also to keep remote as usable as before as possible, meaning that buttons could still be pressed by someone real ;-)
The following gives details about the journey.
- A few words about the remote
- Step 1: Figuring things out
- Step 2: Pressing remote buttons using a micro-controller.
- Step 3: Making it the EspHome/HA way
- A case, just in case ;-)
MAI-EMPX-B1
remote is built around a 868 MHz RF emitter and a HCS301 rolling code / modulator chip. The HCS301 chip can handle up to 4 buttons, only 3 are used here.
A (unsoldered) 4 point connector is accessible in order to program the HCS301 chip (store keys used for KEELOQ, ...)
A diode protect the battery against receiving current from the outside through programming connector.
By the way, in order not to destroy any existing remote, it s a good idea to search for a spare one. A brand new remote costs more or less 70 Euros but refurbished can be found for half that price.
The wiring of the connector can easily be reversed by testing connections with HCS301 chip as well as with buttons pads on the back side.
Pressing a button pulls input state to Vcc.
As the remote will be connected to a USB-powered ESP board, the battery is no longer needed.
Removing the battery however requires to shunt the protection diode. If not, RF emitter won't be supplied with power.
In order to connect the remote to the ESP, GND
pin has to be provided.
This can be done simply by:
- drilling a fifth connector hole besides
Vcc
- soldering a 5 pin male header on the connector pads
- soldering
Gnd
pin to a ground location elsewhere
The ESP used is an ESP8266-based Wemos D1 mini V3.0
Wiring is the following:
D1 mini side | Remote side |
---|---|
D6 |
Down |
D7 |
Stop |
D8 |
Up |
3.3V |
Vcc |
GND |
GND |
The following Arduino sketch can be used to check if button press are properly emulated by the ESP:
- by pairing the remote with the shutter and see if it rolls,
- by capturing traffic with a Flipper Zero (
Sub-GhZ
->read
/ with scanning frequency set on868MHz
).
To get the D1 board working with Arduino IDE, refer to the official documentation.
#define DOWN D6
#define STOP D7
#define UP D8
#define PULSE_DELAY 500
#define WAIT_DELAY 10000
void setup() {
pinMode(UP, OUTPUT);
pinMode(STOP, OUTPUT);
pinMode(DOWN, OUTPUT);
Serial.begin(9600);
}
void pressButtonAndWait(int pin) {
Serial.println("DOWN");
delay(10000);
digitalWrite(DOWN, HIGH);
delay(500);
digitalWrite(DOWN, LOW);
}
void loop() {
Serial.println("DOWN");
pressButtonAndWait(DOWN);
Serial.println("STOP");
pressButtonAndWait(STOP);
Serial.println("UP");
pressButtonAndWait(UP);
}
To get the D1 board running EspHome firmware, refer to
Getting started
section of the official documentation.
Configuring the EspHome device is pretty straightforward, as buttons can be considered as momentary swicthes.
The cons are nevertheless that physically pressing buttons will no longer work because since GPIO pins are configured as OUTPUT
, LOW
(switch OFF
state) state pulls pin to GND
while pressing button pulls pin to Vcc
.
The resulting configuration file (only relevant sections are shown) is below:
esphome:
name: profalux2esphome
esp8266:
board: d1_mini_lite
# (missing elements like wifi, ... should be inserted here)
# ...
#
switch:
- platform: gpio
pin: D6
id: down
name: "Down"
on_turn_on:
- delay: 500ms
- switch.turn_off: down
restore_mode: ALWAYS_OFF
- platform: gpio
pin: D7
id: stop
name: "Stop"
on_turn_on:
- delay: 500ms
- switch.turn_off: stop
restore_mode: ALWAYS_OFF
- platform: gpio
pin: D8
id: up
name: "Up"
on_turn_on:
- delay: 500ms
- switch.turn_off: up
restore_mode: ALWAYS_OFF
web_server:
port: 80
web_server
section is useful only when using EspHome without HA, to be able to toogle buttons through device dashboard.
In order to bring back physical buttons to life, GPIO pin mode has to be changed to INPUT
when switch is in OFF
state.
The resulting configuration file (only relevant sections are shown) is below:
esphome:
name: profalux2esphome
esp8266:
board: d1_mini_lite
# (missing elements like wifi, ... here)
...
#
substitutions:
down_pin: 'D6'
stop_pin: 'D7'
up_pin: 'D8'
output:
- platform: gpio
pin: ${down_pin}
id: gpio_down
- platform: gpio
pin: ${stop_pin}
id: gpio_stop
- platform: gpio
pin: ${up_pin}
id: gpio_up
switch:
- platform: output
output: gpio_down
id: down
name: "Down"
on_turn_on:
- lambda: |-
pinMode(${down_pin}, OUTPUT);
digitalWrite(${down_pin}, HIGH);
- delay: 500ms
- switch.turn_off: down
on_turn_off:
- lambda: |-
pinMode(${down_pin}, INPUT);
restore_mode: ALWAYS_OFF
- platform: output
output: gpio_stop
id: stop
name: "Stop"
on_turn_on:
- lambda: |-
pinMode(${stop_pin}, OUTPUT);
digitalWrite(${stop_pin}, HIGH);
- delay: 500ms
- switch.turn_off: stop
on_turn_off:
- lambda: |-
pinMode(${stop_pin}, INPUT);
restore_mode: ALWAYS_OFF
- platform: output
output: gpio_up
id: up
name: "Up"
on_turn_on:
- lambda: |-
pinMode(${up_pin}, OUTPUT);
digitalWrite(${up_pin}, HIGH);
- delay: 500ms
- switch.turn_off: up
on_turn_off:
- lambda: |-
pinMode(${up_pin}, INPUT);
restore_mode: ALWAYS_OFF
The original case was too thin to fit the ESP and connectors.
So, thanks to Tam who helped me to understand FreeCad basics and gave me hints to deal with it, i've made a replacement case.
Model files, in STL and STEP format, are availbale under 3D
subfolder. Enjoy it!
Job done!
S.