Geekmagic Ultra: Mini estación meteorológica compatible con ESPHome

Domótica

Después de pasar el asistente de Xiaozhi a ESPHome, me ha saltado este pequeño aparato, el Geekmagic Ultra, un dispositivo con ESP8266 y que permite usarlo de forma nativa como estación meteorológica o bien, ponerlo con ESPHome para poder hacer lo que queramos e integrarlo en nuestro Home Assistant.

Vídeo de la review / tutorial del Geekmagic Ultra con ESPHome

Comandos usados

Para aquellos que queréis tener la lista de comandos listos para copiar y pegar, podéis ver el vídeo y aquí os paso los códigos:

Antes de nada, os muestro el pinout del Geekmagic Ultra:

Ahora, deberíais usar las pinzas y el USB-Uart que muestro en el vídeo.

Para dumpear el esp8266:

Linux:

esptool.py -p /dev/ttyUSBX -b 115200 read_flash 0 0x400000 backup_esp8266.bin

Donde ttyUSBX es el número del puerto que ha pillado el dispositivo USB-UART

Windows:

esptool.py -p COMX -b 115200 read_flash 0 0x400000 backup_esp8266.bin

Donde COMX es el COM de vuestro serie

Este es el último código de ESPHome que muestro en el vídeo (recordad adaptarlo a los nombres de vuestros dispositivos/entidades):

esphome:
  name: geekmagic
  friendly_name: Mini Display TV

esp8266:
  board: esp01_1m

logger:
api:
web_server:
  port: 80

ota:
  - platform: esphome

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "Mini-Display-Tv"
    password: "12345678"

captive_portal:

spi:
  clk_pin: GPIO14
  mosi_pin: GPIO13
  interface: hardware
  id: spihwd

output:
  - platform: esp8266_pwm
    pin: GPIO05
    frequency: 200 Hz
    inverted: true
    id: backlight_pwm

light:
  - platform: monochromatic
    output: backlight_pwm
    name: "Backlight"
    id: backlight
    restore_mode: RESTORE_AND_ON

# ---------------------------------------------------------
# FUENTES CORREGIDAS (Sin duplicados)
# ---------------------------------------------------------
font:
  - file: "gfonts://Roboto"
    id: font_main
    size: 20
    glyphs: "0123456789.,: %°CW"

  - file: "gfonts://Roboto"
    id: font_small
    size: 14
    # He añadido la 'K' mayúscula que faltaba para el "OK"
    glyphs: " !\"%()+,-.:0123456789ABCDEFILMOPRSTUWKabcdefghilmnorstuy°Ññ"

  - file: "materialdesignicons-webfont.ttf"
    id: icon_font
    size: 24
    glyphs: [
      "\U000F0339", # Rayo
      "\U000F050F", # Termometro
      "\U000F0591", # Lavadora
      "\U000F042D", # Impresora
      "\U000F011B"  # Gato
    ]

color:
  - id: c_bg
    hex: "000000" # Negro Fondo
  - id: c_white
    hex: "FFFFFF"
  - id: c_gray
    hex: "333333" # Gris para fondos de barras
  - id: c_accent
    hex: "00D2FF" # Azul Cyan
  - id: c_warn
    hex: "FF9800" # Naranja
  - id: c_alert
    hex: "FF0033" # Rojo
  - id: c_good
    hex: "4CAF50" # Verde

# ---------------------------------------------------------
# SENSORES
# ---------------------------------------------------------
sensor:
  - platform: homeassistant
    id: consumo
    entity_id: sensor.consumocasa_channel_1_power
  - platform: homeassistant
    id: temperatura
    entity_id: sensor.habitacion_1_temperature
  - platform: homeassistant
    id: lavadora
    entity_id: sensor.lavadora_consumo
  - platform: homeassistant
    id: p1s_pc
    entity_id: sensor.p1s_progreso_de_la_impresion
  # Nuevo sensor de nivel de arena (0-100)
  - platform: homeassistant
    id: nivel_arena
    entity_id: sensor.pb01009g25030010664_cat_litter_level

text_sensor:
  - platform: homeassistant
    id: p1s_state
    entity_id: sensor.p1s_print_status


binary_sensor:
  # Nuevo sensor binario de basura llena
  - platform: homeassistant
    id: basura_llena
    entity_id: binary_sensor.pb01009g25030010664_garbage_can_full

time:
  - platform: homeassistant
    id: current_time

# ---------------------------------------------------------
# PANTALLA
# ---------------------------------------------------------
display:
  - platform: mipi_spi
    model: st7789v
    spi_id: spihwd
    dimensions:
      height: 240
      width: 240
    invert_colors: true
    dc_pin: GPIO00
    reset_pin: GPIO02
    color_depth: 16
    update_interval: 5s
    id: disp
    spi_mode: mode3
    lambda: |-
      // Limpiar pantalla
      it.fill(id(c_bg));

      // 1. HEADER
      auto time = id(current_time).now();
      it.printf(120, 5, id(font_small), id(c_white), TextAlign::TOP_CENTER, "%02d:%02d", time.hour, time.minute);
      it.line(10, 25, 230, 25, id(c_gray));

      // 2. DATOS DE CASA
      int y_row1 = 40;
      
      // Consumo
      it.print(40, y_row1, id(icon_font), id(c_warn), TextAlign::TOP_CENTER, "\U000F0339");
      if (id(consumo).has_state()) {
        it.printf(40, y_row1 + 25, id(font_main), id(c_white), TextAlign::TOP_CENTER, "%.0f", id(consumo).state);
        it.printf(40, y_row1 + 45, id(font_small), id(c_gray), TextAlign::TOP_CENTER, "W");
      }

      // Temperatura
      it.print(120, y_row1, id(icon_font), id(c_alert), TextAlign::TOP_CENTER, "\U000F050F");
      if (id(temperatura).has_state()) {
        it.printf(120, y_row1 + 25, id(font_main), id(c_white), TextAlign::TOP_CENTER, "%.1f", id(temperatura).state);
        it.printf(120, y_row1 + 45, id(font_small), id(c_gray), TextAlign::TOP_CENTER, "°C");
      }

      // Lavadora
      Color c_lav = id(c_white);
      if (id(lavadora).state > 5) c_lav = id(c_accent);
      it.print(200, y_row1, id(icon_font), c_lav, TextAlign::TOP_CENTER, "\U000F0591");
      if (id(lavadora).has_state()) {
        it.printf(200, y_row1 + 25, id(font_main), id(c_white), TextAlign::TOP_CENTER, "%.0f", id(lavadora).state);
        it.printf(200, y_row1 + 45, id(font_small), id(c_gray), TextAlign::TOP_CENTER, "W");
      }

      // 3. IMPRESORA P1S (ARRIBA)
      int y_p1s = 110;
      it.filled_rectangle(5, y_p1s, 230, 55, Color(20, 20, 20)); 
      it.print(15, y_p1s + 8, id(icon_font), id(c_white), TextAlign::TOP_LEFT, "\U000F042D");
      it.print(45, y_p1s + 10, id(font_small), id(c_white), TextAlign::TOP_LEFT, "Bambu P1S");

      std::string info_p1s = "---";
      Color st_color_p1s = id(c_gray);
      std::string raw_p1s = id(p1s_state).state;
      
      if (raw_p1s == "running" || raw_p1s == "printing") { info_p1s = "Print"; st_color_p1s = id(c_good); }
      else if (raw_p1s == "finish") { info_p1s = "Done"; st_color_p1s = id(c_accent); }
      else if (raw_p1s == "idle") { info_p1s = "Idle"; st_color_p1s = id(c_gray); }
      else { info_p1s = raw_p1s; }

      it.printf(225, y_p1s + 10, id(font_small), st_color_p1s, TextAlign::TOP_RIGHT, "%s", info_p1s.c_str());

      it.filled_rectangle(15, y_p1s + 38, 210, 8, id(c_gray)); 
      if (id(p1s_pc).has_state()) {
          float pct_p1s = id(p1s_pc).state;
          int fill_w_p1s = (int)(210 * (pct_p1s / 100.0));
          if (fill_w_p1s > 210) fill_w_p1s = 210;
          if (fill_w_p1s > 0) it.filled_rectangle(15, y_p1s + 38, fill_w_p1s, 8, st_color_p1s);
      }

      // 4. SECCIÓN ARENERO + GATO (ABAJO)
      int y_cat = 180;
      
      // ZONA IZQUIERDA (BARRA ARENA)
      it.print(10, y_cat, id(font_small), id(c_white), TextAlign::TOP_LEFT, "Arena");
      
      if (id(nivel_arena).has_state()) {
        it.printf(160, y_cat, id(font_small), id(c_accent), TextAlign::TOP_RIGHT, "%.0f%%", id(nivel_arena).state);
        
        it.filled_rectangle(10, y_cat + 25, 150, 15, id(c_gray)); // Fondo
        
        float pct_arena = id(nivel_arena).state;
        if (pct_arena > 100) pct_arena = 100;
        if (pct_arena < 0) pct_arena = 0;
        
        int fill_w_arena = (int)(150 * (pct_arena / 100.0));
        Color c_bar_arena = id(c_accent);
        if (pct_arena < 15) c_bar_arena = id(c_alert); // Rojo si queda poca
        
        if (fill_w_arena > 0) {
            it.filled_rectangle(10, y_cat + 25, fill_w_arena, 15, c_bar_arena);
        }
      }

      // ZONA DERECHA (GATO)
      Color c_gato = id(c_good); // Verde por defecto
      
      // Si el sensor binario dice que está lleno, poner ROJO FIJO
      if (id(basura_llena).state) {
          c_gato = id(c_alert); 
      }

      // Dibujar icono
      it.print(200, y_cat + 5, id(icon_font), c_gato, TextAlign::TOP_CENTER, "\U000F011B");
      
      // Texto debajo
      if (id(basura_llena).state) {
         it.print(200, y_cat + 35, id(font_small), id(c_alert), TextAlign::TOP_CENTER, "FULL");
      } else {
         it.print(200, y_cat + 35, id(font_small), id(c_gray), TextAlign::TOP_CENTER, "OK");
      }

Si queréis los links a los productos que he usado en el vídeo, aquí los tenéis:


USB-Uart: https://s.click.aliexpress.com/e/_EzR9oBW
Pinzas Cleqee: https://s.click.aliexpress.com/e/_EHpEAFQ
Cables dupont (deben ser hembra-hembra F-F): https://s.click.aliexpress.com/e/_EIwrOqk
Destornillador: https://s.click.aliexpress.com/e/_EuabsaM

Cupones Aliexpress activos:

✂️ IFPTK8ZE (-2$ para más de 15$)
✂️ IFPD66S3 (-4$ para más de 29$)
✂️ IFPGRIZO (-7$ para más de 49$)
✂️ IFP9BF4K (-10$ para más de 79$)
✂️ IFPOYCQH (-15$ para más de 109$)
✂️ IFPWDRAM (-20$ para más de 159$)
✂️ IFPF3XLF (-30$ para más de 249$)
✂️ IFPXFSGJ (-45$ para más de 369$)
✂️ IFP87CSO (-60$ para más de 499$)

✂️ IFPNW3PU (-3$ para más de 29$)
✂️ IFPSGNN2 (-6$ para más de 59$)
✂️ IFPF71HL (-9$ para más de 89$)
✂️ IFPO2ENC (-16$ para más de 149$)
✂️ IFPEWAKD (-23$ para más de 199$)
✂️ IFPWLEGR (-30$ para más de 269$)
✂️ IFPDVEWH (-40$ para más de 369$)
✂️ IFPL7BLY (-50$ para más de 469$)
✂️ IFPLVL6G (-60$ para más de 599$)
✂️ IFPHDV9P (-70$ para más de 699$)

Encuentra las ofertas:

🔥CUPONES LIMITADOS,¡ATENTO QUE VOLARÁN!🔥Por si queréis más ofertas podéis verlas aquí.
* Si os salen agotados, podéis avisarme en los comentarios e intento buscar nuevos.

¿Quieres montarte tu propio sistema Smart Home?

¿Te gustaría empezar poco a poco teniendo Google Home, Alexa o Home Assistant para controlar las luces, calefacción y otros electrodomésticos de la casa? ¡Te ayudamos! Entra en nuestro Grupo de Telégram de Domótica y también puedes entrar a nuestro Foro de Domótica donde podrás empezar a leer y preguntar tus dudas. Además, si quieres estar al tanto de las ofertas de domótica que salen a diario para poder hacerte un sistema de domótica low cost, entra a nuestro Canal de ofertas de domótica y no te perderás ni una o si lo prefieres y no tienes Telegram, puedes entrar a nuestra página de ofertas de domótica o Smart Home en Facebook. ¡Síguenos también en nuestro Facebook, Twitter o Instagram! ¡Te esperamos!

Si también buscas otro tipo de ofertas, puedes echar un ojo a nuestros otros canales:
* Tecnología en general *
* Juguetes / consolas / Juegos de mesa *
* Manualidades *
Si no tienes Telegram puedes consultar todas las ofertas en Megabazar.es


Descubre más desde Domótica en Casa

Suscríbete y recibe las últimas entradas en tu correo electrónico.

Contestar

Tu e-mail no será publicadoRequired fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*


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

Lost Password

Registro

Descubre más desde Domótica en Casa

Suscríbete ahora para seguir leyendo y obtener acceso al archivo completo.

Seguir leyendo

Domótica en Casa
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.