Aller au contenu

Messages recommandés

Posté(e)

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.

  • Aime 1
  • 2 semaines après...
Posté(e)
Le 25/11/2023 à 19:27, L33thium a dit :

il existerait pas un genre de répertoire de fichiers yaml modbus pour différents appareils à piloter ?

Certains finissent dans le projet, sinon on en trouve sur github.

Si tu me pointes la doc, je peux tenter de le créer.

  • Aime 1
Posté(e)
Il y a 2 heures, L33thium a dit :

Par contre tu crois que c'est jouable pour esphome la particularité dedietrich du changement de rôle maitre/esclave toutes les 5s ?

Sans code: non.

Mais peut-être avec une lambda (dans le yaml, les lambda permettent d'insérer un peu de code). A voir si la "pile" modbus le permet. Le composant RS485 le permet et détecte les conflits d'accès.

Un exemple en lecture/ecriture: Genvex ECO 375, Nibe ERS 10-500, Alpha-Innotec LG 300 ECO B(E) ventilation | devices.esphome.io

Il y a un autre projet ici: esphome_dietrich/dietrich_en.yaml at master · kakaki/esphome_dietrich · GitHub - mais d'après le yaml, je dirais lecture seule. Mais il y a un mapping excel pour la partie slave.

Rejoindre la conversation

Vous pouvez publier maintenant et vous inscrire plus tard. Si vous avez un compte, connectez-vous maintenant pour publier avec votre compte.

Invité
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • Créer...