Here are some pictures (Thanks @drbytes )
The protocol used is not the standard Tuya protocol.
Impossible to integrate it in Home assistant via Tuya.
It was possible to use Tasmota but you had to parse the serial commands in Home assistant. It’s easier in ESPHOME
uart_read_line_sensor.h
#include "esphome.h"
class UartReadLineSensor : public Component, public UARTDevice, public TextSensor {
public:
UartReadLineSensor(UARTComponent *parent) : UARTDevice(parent) {}
void setup() override {
// nothing to do here
}
int readline(int readch, char *buffer, int len)
{
static int pos = 0;
static int checksum = 0;
int rpos;
int temp;
if (pos==0 or pos==1) {
if (readch != 242) {
pos = 0; // frame must begin with F2F2
checksum = 0; // Reset checksum ready for next time
return -1;
}
}
// Calculate Checksum
if (pos>=2 and pos<=18) {
checksum = checksum + readch;
}
temp = (readch / 16);
if (temp < 10)
temp =temp + 48;
else
temp = temp + 55;
buffer[pos*2] = temp;
temp = readch % 16;
if (temp < 10)
temp =temp + 48;
else
temp = temp + 55;
buffer[pos*2+1] = temp;
if (pos==19 and checksum != readch) {
pos = 0;
checksum = 0; // Reset checksum ready for next time
return -3;
}
// Frame must finish with 7E
if (pos==20) {
if (readch==126) {
rpos = pos;
pos = 0; // Reset position index ready for next time
checksum = 0; // Reset checksum ready for next time
return rpos;
} else {
pos = 0;
checksum=0;
return -2;
}
}
pos++;
return -1;
}
void loop() override {
const int max_line_length = 42;
static char buffer[max_line_length];
while (available()) {
if(readline(read(), buffer, max_line_length) > 0) {
publish_state(buffer);
}
}
}
};
eurom.yaml
esphome:
name: eurom
includes:
- uart_read_line_sensor.h
esp8266:
board: esp01_1m
# Enable logging
logger:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "Eurom Fallback Hotspot"
password: "sburLSnBEYI1"
captive_portal:
api:
services:
- service: heater_trigger
variables:
mode: int
swing: int
then:
- uart.write: !lambda |-
if (mode == 0 ) {
return {0xF1,0xF1,0x02,0x10,0x02,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x1A,0x7E};
} else if (mode == 1 and swing == 1) {
return {0xF1,0xF1,0x02,0x10,0x01,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x7E};
} else if (mode == 2 and swing == 1) {
return {0xF1,0xF1,0x02,0x10,0x01,0x01,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x19,0x7E};
} else if (mode == 1 and swing == 0) {
return {0xF1,0xF1,0x02,0x10,0x01,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x19,0x7E};
} else if (mode == 2 and swing == 0) {
return {0xF1,0xF1,0x02,0x10,0x01,0x02,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x1A,0x7E};
} else {
return {};
}
ota:
password: "2f836d76f61876533599b2918cc6c97a"
uart:
rx_pin: 13
tx_pin: 15
baud_rate: 9600
id: uart_bus
text_sensor:
- platform: wifi_info
ip_address:
name: ESP IP Address
ssid:
name: ESP Connected SSID
bssid:
name: ESP Connected BSSID
mac_address:
name: ESP Mac Wifi Address
- platform: custom
id : recieve_txt
lambda: |-
auto my_custom_sensor = new UartReadLineSensor(id(uart_bus));
App.register_component(my_custom_sensor);
return {my_custom_sensor};
text_sensors:
id: "uart_readline"
select:
- platform: template
name: "Mode"
id : "Eurom_mode"
options:
- 'OFF'
- 50%
- 100%
update_interval: 5s
lambda: !lambda |-
std::string val = id(uart_readline).state;
if ( (val[21]=='1') || (val[21]=='4') ) {
return {"OFF"};
} else if (val[21]=='2') {
return {"50%"};
} else if (val[21]=='3') {
return {"100%"};
} else {
return {};
}
set_action:
- logger.log:
format: "Change mode to %s"
args: ["x.c_str()"]
- uart.write: !lambda |-
std::string val = (x.c_str());
if (val == "OFF" ) {
return {0xF1,0xF1,0x02,0x10,0x02,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x1A,0x7E};
}
else if (val == "50%" ) {
return {0xF1,0xF1,0x02,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x7E};
}
else if (val == "100%" ) {
return {0xF1,0xF1,0x02,0x10,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x7E};
} else {
return {};
}
sensor:
- platform: template
name: "Eurom_Temperature"
unit_of_measurement: "°C"
icon: "mdi:thermometer"
device_class: "temperature"
state_class: "measurement"
accuracy_decimals: 0
update_interval: 5s
# Convert hexadecimal string to int
lambda: |-
std::string val = (id(uart_readline).state);
int temp1 = val[28] - 48;
if (temp1 >10) {
temp1 = temp1 - 7;
}
int temp2 = val[29] - 48;
if (temp2 >10) {
temp2 = temp2 - 7;
}
return (temp1*16+temp2);
switch:
- platform: template
name: "Eurom_swing"
id: "Eurom_swing"
lambda: |-
std::string val = id(uart_readline).state;
if (val[11]=='1') {
return 1;
} else if (val[11]=='2') {
return 0;
} else {
return {};
}
turn_on_action:
- logger.log: "Swing Turned On!"
- uart.write: [0xF1,0xF1,0x02,0x10,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x16,0x7E]
turn_off_action:
- logger.log: "Swing Turned Off!"
- uart.write: [0xF1,0xF1,0x02,0x10,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x7E]
- platform: template
name: "Eurom_power"
id: "Eurom_power"
lambda: |-
std::string val = id(uart_readline).state;
if (val[9]=='1') {
return 1;
} else if (val[9]=='2') {
return 0;
} else {
return {};
}
turn_on_action:
- logger.log: "Turn On (mode 2 + Swing)"
- uart.write: [0xF1,0xF1,0x02,0x10,0x01,0x01,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x19,0x7E]
turn_off_action:
- logger.log: "Turn off"
- uart.write: [0xF1,0xF1,0x02,0x10,0x02,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x1A,0x7E]
# Send serial every 60s to get respond from MCU (to update status...)
interval:
- interval: 60s
then:
- uart.write: [0xF1, 0xF1, 0x01, 0x00, 0x01, 0x7E]
Home assistant
This is my first development with ESPHOME. If it can help anyone…