Bonjour,
Un petit partage de mon expérience récente sur des ESP32.
Tout d'abord: le projet. Le but est de lire les informations de mon onduleur (Sofar Solar ME3000) et de mon Linky, de les afficher et de les envoyer sur homeassistant.
L'affichage: écran 2,4", 320x240, doit permettre en un coup d'oeil de voir si on importe ou exporte l'électricité
Le lien homeassistant: en Wifi, MQTT
Le lien Sofar solar: RS485
Le lien linky: port série des familles
Le choix du matériel:
Un ESP32 (WROVER au début, puis ESP32-S2 ensuite)
Un adaptateur RS485-TTL
Une plaque Pitinfo pour le lien linky (je l'avais déjà)
Le choix du logiciel:
J'ai commencé en arduino, mais c'était long et durant le dev j'ai découvert le projet https://esphome.io/
Après 30 minutes de test de ESPHome - et de parcours de la doc, j'ai choisi ESPHome
Le dev:
ESPHome est un réel projet "low code": 80% de mon projet est de la configuration (à la louche, vous pouver fact-checker)
ESPHome permet (et je le conseille fortement) de séparer les fichiers. J'ai donc comme fichiers
powerreporter-s2.yaml: la version ESP32-S2 - décrit la connexion entre les composants et les packages à utiliser
powerreporter-wrover.yaml: la version ESP32 "classique" - abandonnée pour passer au S2 car j'ai choisi pour la carte WROVER un plus grand destin...
secrets.yaml: contient les mots de passe et SSID du Wifi
display.yaml: décrit la connexion de l'écran et l'affichage
teleinfo.yaml: décrit la connexion RS232 et les mesures du linky à remonter dans homeassistant
me3000.yaml: décrit la connexion RS485 et les mesures à remonter de l'onduleur
Les fichiers:
powerreporter.yaml: contient les infos de config/compilation, les modules à charger et en paramètres des modules les pattes à utiliser
# POWER REPORTER
#
# Sends data from Sofar Solar ME300 and Link to Homeassistant
#
# This is the ESP32-S2 mini version
# NOTE: to be able to use both UARTS, we NEED to disable logging (baudrate: 0)
#
esphome:
name: powerreporter
platformio_options:
board_build.extra_flags:
- "-DARDUINO_USB_CDC_ON_BOOT=0" # Allow boh UART to be used with arduino build chain
esp32:
board: lolin_s2_mini
framework:
type: arduino
# type: esp-idf # recommended for ESP32S2
# version: recommended
# # Custom sdkconfig options
# sdkconfig_options:
# COMPILER_OPTIMIZATION_SIZE: y
# # Advanced tweaking options
# advanced:
# ignore_efuse_mac_crc: false
# Disable logging to ensure both IARTs are free to use.
logger:
baud_rate: 0
# level: NONE
# Enable Home Assistant API
api:
password: !secret ha_api_password
ota:
password: !secret esphome_ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: !secret fallback_ssid
password: !secret fallback_password
captive_portal:
#
# ILI TFT 2.2 MAX3485
#
# +5V --1- VCC 3V3 - VCC
# 0V --2- GND 0V - GND
# ESP32S2.D34 --3- CS ESP.D16 RX - RO
# ESP32S2.D40 --4- RESET ESP.D18 - RE/DE
# ESP32S2.D33 --5- DC/RS ESP.D17 TX - DI
# ESP32S2.D35 --6- MOSI/SDI
# ESP32S2.D36 --7- SCLK
# ESP32S2.D38 --8- LED
# ESP32S2.D37 --9- MISO/SDO
#
#
packages:
me3000: !include
file: powerreporter-packages/me3000.yaml
vars:
uart_rx: GPIO21
uart_tx: GPIO16
flow_control: GPIO18
modbus_address: 0x01
teleinfo: !include
file: powerreporter-packages/teleinfo.yaml
vars:
linky_rx: GPIO9
linky_tx: GPIO10
linky_speed: 1200
linky_histo: true
display: !include
file: powerreporter-packages/display.yaml
vars:
disp_clk_pin: GPIO36
disp_mosi_pin: GPIO35
disp_miso_pin: GPIO37
disp_dc_pin: GPIO33
disp_cs_pin: GPIO34
disp_reset_pin: GPIO40
teleinfo.yaml (facile, il y a un module dans esphome):
###############################################
#
# TELEINFO via Linky (ou Sagem)
#
#
###############################################
uart:
- id: uart_linky
rx_pin: ${linky_rx} # eh oui, c'est paramétrable!
tx_pin: ${linky_tx} #
baud_rate: ${linky_speed} # 1200/9600
parity: EVEN
data_bits: 7
teleinfo:
id: myteleinfo
uart_id: uart_linky
update_interval: 12s
historical_mode: ${linky_histo} # true/false
sensor:
- platform: teleinfo
tag_name: "HCHC"
name: "hchc"
device_class: "energy"
state_class: "total"
unit_of_measurement: "Wh"
icon: mdi:flash
teleinfo_id: myteleinfo
- platform: teleinfo
tag_name: "HCHP"
name: "hchp"
device_class: "energy"
state_class: "total"
unit_of_measurement: "Wh"
icon: mdi:flash
teleinfo_id: myteleinfo
- platform: teleinfo
tag_name: "PAPP"
name: "papp"
device_class: "power"
state_class: "measurement"
unit_of_measurement: "VA"
icon: mdi:flash
teleinfo_id: myteleinfo
text_sensor:
- platform: teleinfo
tag_name: "OPTARIF"
name: "optarif"
teleinfo_id: myteleinfo
me3000.yaml (simplifié - seul le début est intéressant, puis quelques exemples de traduction des messages modbus):
#################################################"
# SOFAR Solar ME3000 via Modbus
#--- Usage:
# packages:
# me3000: !include
# file: me3000.yaml
# vars:
# uart_rx: GPIO16
# uart_tx: GPIO17
# flow_control: GPIO5
# modbus_address: 0x01
uart:
- id: uart_modbus
rx_pin: ${uart_rx}
tx_pin: ${uart_tx}
baud_rate: 9600
stop_bits: 1
# debug:
modbus:
id: modbus_sofar
flow_control_pin: ${flow_control} # GPIO05
uart_id: uart_modbus
modbus_controller:
- id: sofarME3000
modbus_id: modbus_sofar
address: ${modbus_address} #modbus device address
update_interval: 30s # 30 seconds check
setup_priority: -10
# command_throttle: 100ms
#sensor:
# 0x0206 UINT16 Grid A voltage (0~1000V - 0.1V)
# 0x0208 SINT16 Grid A current (-20~20A - 0.01A)
# 0x0209 UINT16 Grid B voltage (0~1000V - 0.1V)
# 0x0208 SINT16 Grid B current (-20~20A - 0.01A)
# 0x020A UINT16 Grid C voltage (0~1000V - 0.1V)
# 0x020B SINT16 Grid C current (-20~20A - 0.01A)
# 0x020C UINT16 Grid frequency ( - 0.01Hz)
# 0x020D SINT16 Charge/discharge power (-10~10kW - 0.01kW)
# 0x020E UINT16 Battery voltage (0~100V - 0.1V)
# 0x020F SINT16 Battery charge/discharge current (-100~100A - 0.01A)
# 0x0210 UINT16 Residual battery capacity (0~100% - 1%)
# 0x0211 ? Battery temperature (?)
# 0x0212 SINT16 Feed in/out power (-10~10kW - 0.01kW)
# 0x0213 UINT16 Power of the load (0~10kW - 0.01kW)
# 0x0214 SINT16 Input/Output power (-10~10kW - 0.01kW)
# 0x0215 UINT16 Power of generation (0~10kW - 0.01kW)
# 0x0216 UINT16 EPS output voltage (0.1V)
# 0x0217 UINT16 EPS output power (0.01kW)
# 0x0218 UINT16 Generation of one day (0.01kW)
# 0x0219 UINT16 Power export to grid of today (0.01kW)
# 0x021A UINT16 Power import from grid of today (0.01kW)
# 0x021B UINT16 Today's power consumption (0.01kW)
# 0x021C UINT16*2 Power generation (1kWh)
# 0x021D
# 0x021E UINT16*2 Total energy export (1kWh)
# 0x021F
# 0x0220 UINT16*2 Total energy import (1kWh)
# 0x0221
# 0x0222 UINT16*2 Total consumption (1kWh)
# 0x0223
# 0x022A UINT16 Count down Time
# 0x022B UINT16 Inverter alert message
# 0x022C UINT16 Battery Cycle Time
# 0x022D UINT16 INV bus voltage
# 0x022E UINT16 LLC bus voltage
# 0x022F UINT16 Buck current
# 0x0230 UINT16 Grid R voltage (0.1V)
# 0x0231 UINT16 Grid R current (0.01A)
# 0x0232 UINT16 Grid S voltage (0.1V)
# 0x0233 UINT16 Grid S current (0.01A)
# 0x0234 UINT16 Grid T voltage (0.1V)
# 0x0235 UINT16 Grid T current (0.01A)
# 0x0236 UINT16 Generation current (0-100)
# 0x0237 SINT16 Battery power (reserved)
# 0x0238 SINT16 Inner Temperature (1°C -127~+127)
# 0x0239 SINT16 Heat sink Temperature (1°C -127~+127)
# 0x023A UINT16 Country code
# 0x0234
# - platform: modbus_controller
# modbus_controller_id: sofarME3000
# id: inverter_charge_discharge_power
# name: "inverter_charge_discharge_power"
# address: 0x020D
# unit_of_measurement: "W"
# register_type: read
# value_type: S_WORD
# accuracy_decimalss: 1
# skip_updates: 60
# filters:
# - multiply: 0.01
sensor:
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_charge_discharge_power
name: "inverter_charge_discharge_power"
device_class: "energy"
address: 0x020D
unit_of_measurement: "kW"
register_type: holding
value_type: S_WORD
state_class: "measurement"
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_battery_voltage
name: "inverter_battery_voltage"
address: 0x020E
unit_of_measurement: "V"
accuracy_decimals: 1
register_type: holding
state_class: "measurement"
value_type: U_WORD
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_battery_charge_discharge_current
name: "inverter_battery_charge_discharge_current"
address: 0x020F
device_class: "current"
unit_of_measurement: "A"
accuracy_decimals: 2
state_class: "measurement"
register_type: holding
value_type: S_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_battery_residual_power
name: "inverter_battery_residual_power"
device_class: "battery"
address: 0x0210
unit_of_measurement: "%"
state_class: "measurement"
register_type: holding
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_battery_temperature
name: "inverter_battery_temperature"
device_class: "temperature"
address: 0x0211
unit_of_measurement: "°C"
state_class: "measurement"
register_type: holding
value_type: S_WORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_feed_in_out
name: "inverter_feed_in_out"
address: 0x0212
device_class: "power"
unit_of_measurement: "kW"
accuracy_decimals: 2
state_class: "measurement"
register_type: holding
value_type: S_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_load_power
name: "inverter_load_power"
address: 0x0213
unit_of_measurement: "kW"
device_class: "power"
accuracy_decimals: 2
state_class: "measurement"
register_type: holding
value_type: U_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_input_output_power
name: "inverter_input_output_power"
address: 0x0214
unit_of_measurement: "kW"
device_class: "power"
state_class: "measurement"
accuracy_decimals: 2
register_type: holding
value_type: S_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_power_generation
name: "inverter_power_generation"
address: 0x0215
unit_of_measurement: "kW"
device_class: "power"
state_class: "measurement"
accuracy_decimals: 2
register_type: holding
value_type: U_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_eps_output_voltage
name: "inverter_esp_output_voltage"
address: 0x0216
unit_of_measurement: "V"
state_class: "measurement"
accuracy_decimals: 1
register_type: holding
value_type: U_WORD
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_eps_output_power
name: "inverter_esp_output_power"
address: 0x0217
unit_of_measurement: "kW"
device_class: "power"
state_class: "measurement"
accuracy_decimals: 2
register_type: holding
value_type: U_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_today_generation
name: "inverter_today_generation"
address: 0x0218
device_class: "energy"
unit_of_measurement: "kWh"
state_class: "total"
accuracy_decimals: 2
register_type: holding
value_type: U_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_today_export
name: "inverter_today_export"
address: 0x0219
device_class: "energy"
unit_of_measurement: "kWh"
state_class: "total"
accuracy_decimals: 2
register_type: holding
value_type: U_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_today_import
name: "inverter_today_import"
address: 0x021A
device_class: "energy"
unit_of_measurement: "kWh"
state_class: "total"
accuracy_decimals: 2
register_type: holding
value_type: U_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_today_load_consumption
name: "inverter_today_load_consumption"
address: 0x021B
device_class: "energy"
unit_of_measurement: "kWh"
state_class: "total"
accuracy_decimals: 2
register_type: holding
value_type: U_WORD
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_total_generation
name: "inverter_total_generation"
address: 0x021C
state_class: "total_increasing"
device_class: "energy"
unit_of_measurement: "kWh"
register_type: holding
value_type: U_DWORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_total_export_power
name: "inverter_total_export_power"
address: 0x021E
device_class: "energy"
unit_of_measurement: "kWh"
state_class: "total_increasing"
register_type: holding
value_type: U_DWORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_total_import_power
name: "inverter_total_import_power"
address: 0x0220
device_class: "energy"
unit_of_measurement: "kWh"
state_class: "total_increasing"
register_type: holding
value_type: U_DWORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_total_load_power
name: "inverter_total_load_power"
address: 0x0222
device_class: "energy"
unit_of_measurement: "kWh"
state_class: "total_increasing"
register_type: holding
value_type: U_DWORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_generation_current
name: "inverter_generation_current"
address: 0x0236
device_class: "current"
unit_of_measurement: "A"
state_class: "measurement"
register_type: holding
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_inner_temperature
name: "inverter_inner_temperature"
device_class: "temperature"
address: 0x0238
unit_of_measurement: "°C"
state_class: "measurement"
register_type: holding
value_type: S_WORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_heatsink_temperature
name: "inverter_heatsink_temperature"
device_class: "temperature"
address: 0x0239
unit_of_measurement: "°C"
state_class: "measurement"
register_type: holding
value_type: S_WORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_country
name: "inverter_country"
address: 0x023A
register_type: holding
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_dc_current
name: "inverter_dc_current"
address: 0x023B
device_class: "current"
unit_of_measurement: "A"
accuracy_decimals: 3
state_class: "measurement"
register_type: holding
value_type: U_DWORD
filters:
- multiply: 0.001
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: inverter_dc_voltage
name: "inverter_dc_voltage"
address: 0x023C
unit_of_measurement: "V"
accuracy_decimals: 1
state_class: "measurement"
register_type: holding
value_type: U_DWORD
filters:
- multiply: 0.1
##########################################################################
# BINARY sensors
#
# For the ME3000, binary sensors essentially are bits set for fault
# and diagnostic messages
#
#########################################################################
binary_sensor:
- platform: modbus_controller
modbus_controller_id: sofarME3000
name: ID01 Grid Over Voltage Protection
entity_category: diagnostic
device_class: problem
register_type: read
address: 0x201
bitmask: 0x1
- platform: modbus_controller
modbus_controller_id: sofarME3000
name: ID02 Grid Under Voltage Protection
entity_category: diagnostic
device_class: problem
register_type: read
address: 0x201
bitmask: 0x2
- platform: modbus_controller
modbus_controller_id: sofarME3000
name: ID03 Grid Over Frequency Protection
entity_category: diagnostic
device_class: problem
register_type: read
address: 0x201
bitmask: 0x4
- platform: modbus_controller
modbus_controller_id: sofarME3000
name: ID04 Grid Under Frequency Protection
entity_category: diagnostic
device_class: problem
register_type: read
address: 0x201
bitmask: 0x8
- platform: modbus_controller
modbus_controller_id: sofarME3000
name: ID05 Battery Over Voltage
entity_category: diagnostic
device_class: problem
register_type: read
address: 0x201
bitmask: 0x10
- platform: modbus_controller
modbus_controller_id: sofarME3000
name: ID06 RESERVED
entity_category: diagnostic
device_class: problem
register_type: read
address: 0x201
bitmask: 0x20
- platform: modbus_controller
modbus_controller_id: sofarME3000
name: ID07 RESERVED
entity_category: diagnostic
device_class: problem
register_type: read
address: 0x201
bitmask: 0x40
- platform: modbus_controller
modbus_controller_id: sofarME3000
name: ID08 RESERVED
entity_category: diagnostic
device_class: problem
register_type: read
address: 0x201
bitmask: 0x80
- platform: modbus_controller
modbus_controller_id: sofarME3000
name: ID09 LLCBus Over Voltage Hardware Protection
entity_category: diagnostic
device_class: problem
register_type: read
address: 0x201
bitmask: 0x100
##########################################################################
# TEXT sensors
#
# For the ME3000, text sensors are states
#
#########################################################################
text_sensor:
# 0x0200
- platform: modbus_controller
modbus_controller_id: sofarME3000
id: running_state
bitmask: 0
register_type: holding
address: 0x200
raw_encode: HEXBYTES
name: running_state
lambda: |-
uint16_t value = modbus_controller::word_from_hex_str(x, 0);
switch (value) {
case 0: return std::string("Wait");
case 1: return std::string("Check");
case 2: return std::string("Normal");
case 3: return std::string("Check Discharge");
case 4: return std::string("Discharge");
case 5: return std::string("EPS");
case 6: return std::string("Fault");
case 7: return std::string("Permanent Fault");
default: return std::string("Unknown state");
}
return x;
et display.yaml (noter l'usage des couleurs, des images, tout est géré par esphome):
###############################################################
#
# TFT Display config
#
# vars:
# disp_clk_pin: GPIO18 / GPIO14
# disp_mosi_pin: GPIO13 / GPIO23
# disp_miso_pin: GPIO12 / GPIO29
# disp_cs_pin:
# disp_reset_pin:
#
###############################################################
spi:
id: spi_display
clk_pin: ${disp_clk_pin} # GPIO14 / VSPI-GPIO18
mosi_pin: ${disp_mosi_pin} # GPIO13 / VSPI-GPIO23
miso_pin: ${disp_miso_pin} # GPIO12 / VSPI-GPIO19
font:
- file: "gfonts://Roboto"
id: mono20
size: 20
- file: "gfonts://Roboto"
id: mono16
size: 16
- file: "gfonts://Roboto"
id: mono8
size: 10
color:
- id: text_alert
red: 100%
green: 70%
blue: 10%
- id: text_danger
red: 100%
green: 17%
blue: 10%
- id: text_info
red: 80%
green: 80%
blue: 80%
- id: text_success
red: 10%
green: 100%
blue: 17%
sensor:
- platform: wifi_signal # Reports the WiFi signal strength/RSSI in dB
name: "WiFi Signal dB"
id: wifi_signal_db
update_interval: 30s
entity_category: "diagnostic"
- platform: copy # Reports the WiFi signal strength in %
source_id: wifi_signal_db
name: "WiFi Signal Percent"
filters:
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
unit_of_measurement: "Signal %"
entity_category: "diagnostic"
image:
- id: img_sun_on
file: mdi:weather-sunny
resize: 40x40
- id: img_sun_off
file: mdi:weather-sunny-off
resize: 40x40
- id: img_grid_power_on
file: mdi:transmission-tower
resize: 40x40
- id: img_grid_power_off
file: mdi:transmission-tower-off
resize: 40x40
- id: img_grid_power_import
file: mdi:transmission-tower-import
resize: 40x40
- id: img_grid_power_export
file: mdi:transmission-tower-export
resize: 40x40
- id: img_battery_high
file: mdi:battery-high
resize: 40x40
- id: img_battery_medium
file: mdi:battery-medium
resize: 40x40
- id: img_battery_low
file: mdi:battery-low
resize: 40x40
- id: img_battery_empty
file: mdi:battery-outline
resize: 40x40
- id: img_battery_off
file: mdi:battery-off
resize: 40x40
- id: img_battery_unknown
file: mdi:battery-unknown
resize: 40x40
- id: img_home_import_big
file: mdi:home-import-outline
resize: 80x80
- id: img_home_export_big
file: mdi:home-export-outline
resize: 80x80
- id: img_grid_power_big
file: mdi:transmission-tower
resize: 80x80
#
# Display is in 3 areas:
# Upper area: current battery level /sun production / total load
#
# Center: iconic represantation: grid to home or home to grid
# Total energy
#
# Lower: page 1: totals
# page 2: temperatures...
#
display:
- platform: ili9xxx
spi_id: spi_display
model: ili9341 # MSSTACK, TFT 2.4, TFT 2.4R, S3BOX, S3BOX_LITE, ILI9341, ILI9342, ILI9481, ILI9486, ILI9488, ILI9488_A
cs_pin: ${disp_cs_pin}
dc_pin: ${disp_dc_pin}
reset_pin: ${disp_reset_pin}
rotation: 90 # 180, 270
# data_rate: 20MHz
# color_palette: GRAYSCALE
# dimensions: 320x240
lambda: |-
it.fill(Color::BLACK);
// UPPER AREA:
// Left: battery status Center: solar production Right: total Load
if (isnan(id(inverter_battery_residual_power).state))
{
it.image(0,0,id(img_battery_unknown));
it.printf(50,10,id(mono16),id(text_alert),"? %%");
} else {
if(id(inverter_battery_residual_power).state > 80)
it.image(0,0,id(img_battery_high));
else if(id(inverter_battery_residual_power).state > 50)
it.image(0,0,id(img_battery_medium));
else if(id(inverter_battery_residual_power).state > 25)
it.image(0,0,id(img_battery_low));
else
it.image(0,0,id(img_battery_empty));
it.printf(50,10,id(mono16),id(text_success),"%.0f %%",id(inverter_battery_residual_power).state);
}
// solar production: if 0 or less: sun icon is dashed, else sun icon is bright
if (id(inverter_power_generation).state > 0)
{ // generating photo voltaic
it.image(100,0,id(img_sun_on));
it.printf(150,10,id(mono16),id(text_success),"%.1f kWh",id(inverter_power_generation).state);
} else {
it.image(100,0,id(img_sun_off));
it.printf(150,10,id(mono16),id(text_danger),"%.1f kWh",id(inverter_power_generation).state);
}
// total load
if (id(inverter_load_power).state > 0)
{ // exporting
it.image(200,0,id(img_grid_power_import));
it.printf(250,10,id(mono16),id(text_success)," %.1f kWh",id(inverter_load_power).state);
} else {
it.image(200,0,id(img_grid_power_export));
it.printf(250,10,id(mono16),id(text_danger)," %.1f kWh",id(inverter_load_power).state);
}
// CENTER AREA
// Grid + Home + arrow
if (id(inverter_feed_in_out).state >= 0) {
// Production !!!
//it.image(40,50,id(img_grid_power_big)); // grid
it.image(160-80/2,50,id(img_home_export_big)); // home
it.image(320-40-80,50,id(img_grid_power_big)); // grid
it.printf(160-80/2,140,id(mono20),id(text_info),"+ %.2f kWh",id(inverter_load_power).state);
} else {
// Production !!!
it.image(40,50,id(img_grid_power_big)); // grid
it.image(160-80/2,50,id(img_home_import_big)); // home
//it.image(320-40-80,50,id(img_grid_power_big)); // grid
it.printf(160-80/2,140,id(mono20),id(text_danger),"- %.2f kWh",id(inverter_load_power).state);
}
// Lower part
it.printf(0,190,id(mono8),id(text_info),"Tot Exp°: %.0f kWh",id(inverter_today_export).state);
it.printf(100,190,id(mono8),id(text_info),"Tot Sol°: %.0f kWh",id(inverter_today_generation).state);
it.printf(200,190,id(mono8),id(text_info),"Tot Imp°: %.0f kWh",id(inverter_today_import).state);
it.printf(0,215,id(mono8),id(text_info),"BAT T°: %.0f °C",id(inverter_battery_temperature).state);
it.printf(100,215,id(mono8),id(text_info),"INN T°: %.0f °C",id(inverter_inner_temperature).state);
it.printf(200,215,id(mono8),id(text_info),"HEA T°: %.0f °C",id(inverter_heatsink_temperature).state);
Au final:
J'ai passé moins de 2 heures à noter tout ce que ESPHome allait m'apporter (gestion du RS485, module téléinfo, affichage)
Implémenter les packages m'a pris en gros 2 heures
A peu près 2h pour la mise au point de l'affichage (je suis revenu plusieurs fois sur mes idées)
Et bonnes heures à débugguer à cause su choix du ESP32-S2 qui est limité niveau UART: préférez le ESP32 WROOM si possible
80% du temps, on ajoute juste des lignes pour dire "activer ci, activer ça": il n'y a du code que dans l'affichage (et très répétitif) et dans un des sensors (que je n'utilise pas en plus)
En conclusion: ESPHome est un super projet, compatible ESP32 et RPI pico, permettant de créer très rapidement des objets IOT connectés en MQTT et nativement détecté dans homeassistant.