Saltar al contenido
Inicio » Monitor de producción fotovoltaica IoT con ESPHome (Segunda parte, Software)

Monitor de producción fotovoltaica IoT con ESPHome (Segunda parte, Software)

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.

Probando el dispositivo montado sobre una placa
Soldaduras… son mejorables, a verdad.
Dispositivo final mostrando datos e iluminando en verde por la exportacion de energia a la red.

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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.