Este pequeño monitor debe hacer una tarea muy simple, recoger datos por MQTT de la pinza amperimétrica que mide la producción fotovoltaica y consumos de la casa y poder mostrarlos en su display. Voy a ir mostrando partes del código y detallando brevemente que hace para mostrar lo sencillo que es realizar algo así con ESPHome. Asi se debe iniciar el código de ESPHome y darle un nombre a nuestra creación.
esphome: name: energydisplay
Debemos definir el tipo de placa con el que vamos a trabajar, ya que no todas son iguales, en mi caso esp32dev
esp32:
board: esp32dev
framework:
type: arduino
Activar o desactiva el logger
# Enable logging logger: # level: very_verbose
Nos permite poder actualizar por WIFI
ota: password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Definición de la red WIFI, guardados en el menú secrets de ESPhome
wifi: ssid: !secret wifi_ssid password: !secret wifi_password
Creación de su propio punto de acceso si no puede conectarse a la WIFI y desde ahí se puede controlar.
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Energydisplay Fallback Hotspot"
password: "xxxxxxxxxxx"
MQTT: aquí empieza la parte interesante. Le indicamos cual es nuestro bróker de MQTT y los mensajes que debe obtener con subscribe. Con la función lambda simplemente miramos si estamos comprando luz para generar una variable que nos indica si ponemos el led en verde al vender o rojo al comprar
mqtt:
broker: 192.168.1.18
discovery_unique_id_generator: mac
on_json_message:
topic: inversor/shelly
then:
- if:
condition:
lambda: 'return x["comprando_luz"] == 0 ;'
then:
- output.turn_on: led_verde
- output.turn_off: led_rojo
else:
- output.turn_off: led_verde
- output.turn_on: led_rojo
Con sensor creamos los sensores propios que tenemos de temperatura y humedad y generamos las variables con los que provienen de MQTT
sensor:
#mqtt
- platform: mqtt_subscribe
name: "Energia Calle"
id: sensor_potencia_calle
topic: shellies/shellyem1/emeter/0/power
- platform: mqtt_subscribe
name: "Produccion Solar"
id: sensor_potencia_solar
topic: shellies/shellyem1/emeter/1/power
- platform: mqtt_subscribe
name: "Consumo Casa"
id: sensor_consumo_casa
topic: energydisplay/W_casa
#dth22 temperatura
- platform: dht
pin: GPIO2
temperature:
name: "Temperatura Despacho"
id: temp_salon
humidity:
name: "Humedad Despacho"
id: humedad_salon
update_interval: 30s
model: DHT22
Con NTP tendremos sincronización horaria y podremos mostrar la hora en el display.
#NTP
time:
- platform: sntp
id: sntp_time
timezone: 'Europe/Madrid'
servers:
- 0.es.pool.ntp.org
- 1.es.pool.ntp.org
- 2.es.pool.ntp.org
Imágenes es la sección donde cargamos los pequeños iconos que mostraremos en pantalla.
#carga de imagenes
image:
- file: "temperature-celsius.png"
id: img_celsius
resize: 12x12
- file: "thermometer.png"
id: img_thermometer
resize: 12x12
- file: "solar-panel.png"
id: img_solar
resize: 18x18
- file: "home.png"
id: img_home
resize: 18x18
- file: "grid.png"
id: img_grid
resize: 20x20
En esta sección cargamos las fuentes necesarias para escribir datos en pantalla. Cada tamaño necesita su fuente
# carga de fuentes
font:
- file: 'Cousine.ttf'
id: my_double_font
size: 16
- file: 'Cousine.ttf'
id: my_font
size: 24
- file: 'Cousine.ttf'
id: my_small_font
size: 12
Define como está conectada la pantalla y en que pines, en este caso es por SPI, pero depende del display. En lambda definimos los iconos, textos con su fuente y las posiciones donde se muestran datos en pantalla
# puerto pantalla
spi:
clk_pin: GPIO14
mosi_pin: GPIO13
# oled display
display:
- platform: ssd1306_spi
model: "SSD1306 128x64"
reset_pin: GPIO17
cs_pin: GPIO5
dc_pin: GPIO16
lambda: |-
it.image(0, 0, id(img_thermometer),COLOR_OFF,COLOR_ON);
it.printf(15, 0, id(my_small_font), "%.1f", id(temp_salon).state);
it.image(45,0, id(img_celsius),COLOR_OFF,COLOR_ON);
it.strftime(94, 0, id(my_small_font), "%H:%M", id(sntp_time).now());
it.image(0,16, id(img_grid),COLOR_OFF,COLOR_ON);
it.printf(22, 16, id(my_font), "%5.0fw", id(sensor_potencia_calle).state);
it.image(0,44, id(img_solar),COLOR_OFF,COLOR_ON);
it.printf(22, 44, id(my_double_font), "%4.0f", id(sensor_potencia_solar).state);
it.image(64,44, id(img_home),COLOR_OFF,COLOR_ON);
it.printf(84, 44, id(my_double_font), "%4.0f", id(sensor_consumo_casa).state);
Aquí solo indicamos los pines de los led para activarlos están asociados a las variables que cambian en la sección de MQTT
#PINes leds
output:
- id: led_verde
platform: gpio
pin: GPIO12
- id: led_rojo
platform: gpio
pin: GPIO33
Y eso es todo, realmente sencillo.



Aqui tambien dejo el código completo, mas que nada para facilitar el copiado si fuera necesario y tener una base de la que partir si alguien quiere hacer un dispositivo parecido,
esphome:
name: energydisplay
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# level: very_verbose
ota:
password: "xxxxxxxxxxxxxxxxxxxxxxxxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Energydisplay Fallback Hotspot"
password: "xxxxxxxxxxx"
captive_portal:
#conexion mqtt
mqtt:
broker: 192.168.x.x
discovery_unique_id_generator: mac
on_json_message:
topic: inversor/shelly
then:
- if:
condition:
lambda: 'return x["comprando_luz"] == 0 ;'
then:
- output.turn_on: led_verde
- output.turn_off: led_rojo
else:
- output.turn_off: led_verde
- output.turn_on: led_rojo
sensor:
#mqtt
- platform: mqtt_subscribe
name: "Energia Calle"
id: sensor_potencia_calle
topic: shellies/shellyem1/emeter/0/power
- platform: mqtt_subscribe
name: "Produccion Solar"
id: sensor_potencia_solar
topic: shellies/shellyem1/emeter/1/power
- platform: mqtt_subscribe
name: "Consumo Casa"
id: sensor_consumo_casa
topic: energydisplay/W_casa
#dth22 temperatura
- platform: dht
pin: GPIO2
temperature:
name: "Temperatura Despacho"
id: temp_salon
humidity:
name: "Humedad Despacho"
id: humedad_salon
update_interval: 30s
model: DHT22
#NTP
time:
- platform: sntp
id: sntp_time
timezone: 'Europe/Madrid'
servers:
- 0.es.pool.ntp.org
- 1.es.pool.ntp.org
- 2.es.pool.ntp.org
#carga de imagenes
image:
- file: "temperature-celsius.png"
id: img_celsius
resize: 12x12
- file: "thermometer.png"
id: img_thermometer
resize: 12x12
- file: "solar-panel.png"
id: img_solar
resize: 18x18
- file: "home.png"
id: img_home
resize: 18x18
- file: "grid.png"
id: img_grid
resize: 20x20
# carga de fuentes
font:
- file: 'Cousine.ttf'
id: my_double_font
size: 16
- file: 'Cousine.ttf'
id: my_font
size: 24
- file: 'Cousine.ttf'
id: my_small_font
size: 12
# puerto pantalla
spi:
clk_pin: GPIO14
mosi_pin: GPIO13
# oled display
display:
- platform: ssd1306_spi
model: "SSD1306 128x64"
reset_pin: GPIO17
cs_pin: GPIO5
dc_pin: GPIO16
lambda: |-
it.image(0, 0, id(img_thermometer),COLOR_OFF,COLOR_ON);
it.printf(15, 0, id(my_small_font), "%.1f", id(temp_salon).state);
it.image(45,0, id(img_celsius),COLOR_OFF,COLOR_ON);
it.strftime(94, 0, id(my_small_font), "%H:%M", id(sntp_time).now());
it.image(0,16, id(img_grid),COLOR_OFF,COLOR_ON);
it.printf(22, 16, id(my_font), "%5.0fw", id(sensor_potencia_calle).state);
it.image(0,44, id(img_solar),COLOR_OFF,COLOR_ON);
it.printf(22, 44, id(my_double_font), "%4.0f", id(sensor_potencia_solar).state);
it.image(64,44, id(img_home),COLOR_OFF,COLOR_ON);
it.printf(84, 44, id(my_double_font), "%4.0f", id(sensor_consumo_casa).state);
#PINes leds
output:
- id: led_verde
platform: gpio
pin: GPIO12
- id: led_rojo
platform: gpio
pin: GPIO33