Installing ESPhome on GEEKMAGIC Smart Weather Clock (smalltv/pro)

I fixed it, thanks to several other posts.


esphome:
  name: smalltv
  friendly_name: SmallTV
  platform: ESP8266
  board: esp01_1m

external_components:
  - source:
      type: git
      url: https://github.com/rletendu/esphome.git
      ref: st7789_nobuffer_202312
    # refresh: 0s
    components: [st7789v]

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
        key: !secret key_smallTV

ota:
  - platform: esphome
    password: !secret ota_smallTV

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Cash From Cahos"
    password: "CFC_Rules_Since_69"

# Ici, on active le serveur WEB du ESP8266, en allant sur l'IP du ESP8266, on tombe sur une interface pour piloter les relais
web_server:
  port: 80
  auth:
    username: !secret server_username
    password: !secret server_password

captive_portal:

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

# status_led:
#   pin: GPIO2

time:
  - platform: homeassistant
    id: ha_time

output:
  - platform: esp8266_pwm
    pin: GPIO05
    frequency: 40 Hz
    id: pwm_output

light:
  - platform: monochromatic
    output: pwm_output
    name: "Backlight"

font:
  - file: "SFCompact.ttf"
    id: roboto
    size: 30
    glyphs: 'éèà!"%()+,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz/'


display:
  - platform: st7789v
    model: "Custom"
    spi_id: spihwd
    height: 240
    width: 240
    offset_height: 0
    offset_width: 0
    # dc_pin: GPIO02
    # reset_pin: GPIO04
    dc_pin: GPIO00
    reset_pin: GPIO02
    #backlight_pin: GPIO25
    eightbitcolor: True
    #update_interval: never
    update_interval: 30s
    id: disp
    spi_mode: mode3
    lambda: |-
      // Calculate the center positions
      int center_x = it.get_width() / 2;
      int center_y = it.get_height() / 2;

      // Print "Hello World" centered
      it.printf(center_x, center_y - 20, id(roboto), TextAlign::CENTER, "Hello World");

      // Print the current time centered below "Hello World"
      auto time = id(ha_time).now();
      time_t time_t_value = time.timestamp;
      char buf[9]; // Buffer to hold the time string
      strftime(buf, sizeof(buf), "%H:%M:%S", localtime(&time_t_value));
      it.printf(center_x, center_y + 20, id(roboto), TextAlign::CENTER, buf);

5 Likes

I created an ESPHome configuration for the low-end GeekMagic TV. It supports displaying three text pages with basic formatting and includes a notification service. The page rotation speed can be adjusted, and a specific page can also be set as fixed. It might not be completely bug-free, but it has been working well for me so far. I wrote it with a lot of help from Copilot. :wink:

Code is here: GeekMagic Display Small TV ESPHome Config Ā· GitHub

7 Likes

I’ve made some updates to my ESPHome configuration for the low-end GeekMagic TV:
• Added support for five pages (up from three).
• Included a number input to set a max page for rotation.
• Implemented an error message if the sensor for the text isn’t set up in Home Assistant.
• Added more buttons and services to switch pages.
• Changed the font and font sizes.
• Improved the calculation for new lines, making it better and cleaner.
• Included a startup message since sensors from Home Assistant need to load before the first display.
• Added an action to update the display content whenever the sensor text value is updated in Home Assistant.
• Included a switch to activate/deactivate this last behavior.

These changes make the setup more flexible and user-friendly. Let me know what you think or if you encounter any issues!

I edit the code on the first post.

3 Likes

I’ve made some updates to my ESPHome configuration for the low-end GeekMagic TV:

  • Removed Large Font and restricted glyphs the because the fonts needs to much of the ram
  • Added two progress bars on top and bottom. The values are loaded from home assistant number sensors
  • added a display buzzer for alarming
  • changed the font rendering
  • added the status led light
  • changed the name schema for the home assistant sensors to make it easy to support more than one device
  • Removed unnecessary sensors and the logger to save RAM.
  • Added an option to create two columns on a page.
  • Enabled displaying a page initially in the bottom right corner.
  • Included the API key in the API configuration for potential REST API functionality (not thoroughly tested yet).
  • Updated the web server GUI to a newer, more user-friendly version.
  • Added sorting to the web server UI.
  • Settings are now saved between reboots.
  • Fixed issues with display and sensor updates.
  • Notifications are now queued for better handling.

I edit the code on the first post.

6 Likes

For which version is this?

-smallTV
-PRO
-ULTRA

Not sure what the ULTRA version is, but it pops up from time to time [in the bundle-deals of Aliexpress]

Congratulations, Great job!!
I can show several HA sensors but I don’t understand how you can modify the size, position, color, etc.

Can someone give me a hand I’m trying to implement an MVP, to start working on that but seems that the flashing is okay but when I plug in the screen is black and on HA the device is offline

I have the smalltv (without pro) version

esphome:
  name: smalltv
  platform: ESP8266
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "-"

ota:
  - platform: esphome
    password: "-"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# SPI bus for the display
spi:
  clk_pin: GPIO14
  mosi_pin: GPIO13

# Display configuration
display:
  - platform: ili9xxx
    model: ili9341
    cs_pin: GPIO15
    dc_pin: GPIO2
    reset_pin: GPIO0
    rotation: 0
    invert_colors: false
    show_test_card: true
    lambda: |-
      it.print(10, 10, id(my_font), "Hello, World!");

# Font configuration
font:
  - file: "fonts/arial.ttf"
    id: my_font
    size: 20

Hi guys! I’m really glad that I found this.
I purchase a clone of this device, and I’m just using as a weather clock, tbh, but I didn’t like the design. So I was looking how to program my personal taste on it. And only after fiding this I was able to make the display alive.
I’m really beggining in this code world.
Next step is learning how to use API for my home devices and my google calendar.
But right now all I want is to discover how to set the brightness of the display. I’m having hugh trouble, try many ways but nothing works. If anyone know how to do it, and could give me a tip, that’s all I ask.
Thankyou so much.

Mine is just like this one, already sent here

Thats it right now

1 Like

Google drive folder with some informations and files for smart weather clock (aliexpress):
https://drive.google.com/drive/folders/1kfawx8x7GTcZL8NVQciQRdZpN6FcyqHo

1 Like

I would really like to use the device as a monitor for energy consumption using the color of the base to indicate green production, red consumption. Have you managed to interface it with HA?

Hi
@rletendu can you post an updated version?
I have ESPhome as docker (on a separate machine) and the config doesnt work anymore.
I“ve figured that i have to download the fonts directly:

  - file: 'https://github.com/Templarian/MaterialDesign-Webfont/raw/refs/heads/master/fonts/materialdesignicons-webfont.ttf'
  - file: 'https://github.com/edx/edx-fonts/raw/refs/heads/master/open-sans/fonts/Regular/OpenSans-Regular.ttf'

But i guess there is an issue with the lambda at the end …iĀ“ll always get

Traceback (most recent call last):
  File "/usr/local/bin/esphome", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/esphome/esphome/__main__.py", line 1049, in main
    return run_esphome(sys.argv)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 1036, in run_esphome
    rc = POST_CONFIG_ACTIONS[args.command](args, config)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 503, in command_run
    exit_code = write_cpp(config)
                ^^^^^^^^^^^^^^^^^
  File "/esphome/esphome/__main__.py", line 212, in write_cpp
    generate_cpp_contents(config)
  File "/esphome/esphome/__main__.py", line 224, in generate_cpp_contents
    CORE.flush_tasks()
  File "/esphome/esphome/core/__init__.py", line 674, in flush_tasks
    self.event_loop.flush_tasks()
  File "/esphome/esphome/coroutine.py", line 246, in flush_tasks
    next(task.iterator)
  File "/esphome/esphome/__main__.py", line 204, in wrapped
    await coro(conf)
  File "/config/.esphome/external_components/600432c8/esphome/components/st7789v/display.py", line 164, in to_code
    await display.register_display(var, config)
  File "/esphome/esphome/components/display/__init__.py", line 136, in register_display
    await cg.register_component(var, config)
  File "/esphome/esphome/cpp_helpers.py", line 53, in register_component
    raise ValueError(
ValueError: Component ID disp was not declared to inherit from Component, or was registered twice. Please create a bug report with your configuration.

Looking for help. Thank you.

Hello, can you share your complete code?

This is really cool. I have this one and the firmware is really lacking compared to the original Geek Magic. I was hoping to learn to customize it myself. Can you share how you got to rewrite the firmware? Thanks

This is some more info I found on development of this device : Installing Tasmota on GeekMagic SmallTV look alike device Ā· arendst/Tasmota Ā· Discussion #21791 Ā· GitHub

I asked the seller / creator / support guy for the source code to their firmware and they said they won’t give it out so I’d rather make my own than connect this thing to my network. I should have bought GeekMagic since it is open source.

if it helps, I have the backlight adjustable on mine. State is saved on power cycle. mine is an esp8266 based ali express variant. this has some other logic you may not want though beyond that, so id just snip the parts you need

esphome:
  name: mini-display-tv-yellow
  friendly_name: Mini Display TV - Yellow

esp8266:
  board: esp01_1m

external_components:
  - source:
      type: git
      url: https://github.com/rletendu/esphome.git
      ref: st7789_nobuffer_202312
    components: [st7789v]

logger:

api:

ota:
  platform: esphome

wifi:
  ssid: "wifinetwork"
  password: "wifipassword"
  ap:
    ssid: "Mini-Display-Tv--Yellow"
    password: "wifipassword"

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

output:
  - platform: esp8266_pwm
    pin: GPIO05
    frequency: 1000 Hz
    id: pwm_output
    inverted: true

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

font:
  - file: "gfonts://Atkinson Hyperlegible"
    id: dspfont
    size: 75

  - file: "gfonts://Atkinson Hyperlegible"
    id: dspfont_small
    size: 30

  - file: "gfonts://Atkinson Hyperlegible"
    id: dspfont_medium
    size: 40

  - file: "gfonts://Atkinson Hyperlegible"
    id: dspfont_am_pm
    size: 20

color:
  - id: color_white
    red: 100%
    green: 100%
    blue: 100%
  - id: color_green
    red: 0%
    green: 100%
    blue: 0%

time:
  - platform: homeassistant
    id: esptime

switch:
  - platform: homeassistant
    id: air_purifier_outlet1
    entity_id: switch.air_purifier_outlet1

display:
  - platform: st7789v
    model: "Custom"
    spi_id: spihwd
    height: 240
    width: 240
    offset_height: 0
    offset_width: 0
    dc_pin: GPIO00
    reset_pin: GPIO02
    eightbitcolor: true
    update_interval: 15s
    id: disp
    spi_mode: mode3
    lambda: |-
      Color text_color = id(color_white);
      if (id(air_purifier_outlet1).state) {
        text_color = id(color_green);
      }
      // Display the time in 12-hour format
      it.strftime(0, 60, id(dspfont), text_color, TextAlign::BASELINE_LEFT, "%l:%M", id(esptime).now());
      
      // Display AM/PM (Using %p to show AM/PM text)
      it.strftime(230, 42, id(dspfont_am_pm), text_color, TextAlign::BASELINE_RIGHT, "%p", id(esptime).now());
      
      // Display the date in abbreviated weekday, MM/DD format (no year)
      it.strftime(0, 110, id(dspfont_medium), text_color, TextAlign::BASELINE, "%a %m/%d", id(esptime).now());
      
      // Display "Party mode: ON" or "No fun allowed"
      if (id(air_purifier_outlet1).state) {
        it.printf(0, 230, id(dspfont_small), text_color, TextAlign::BASELINE_LEFT, "Party mode: ON");
      } else {
        it.printf(0, 230, id(dspfont_small), text_color, TextAlign::BASELINE_LEFT, "No fun allowed");
      }

edit: cleaned up mess in yaml, I didn’t want to have such a horrid example

2 Likes

For @TheHexer

https://drive.google.com/drive/folders/1cjTZFKQrkLYICUGu_tOGyAIwtyaDrm_W

Sorry for the noob question but what’s the easiest way to get ESPhome on the clone variant?

Plug it into your PC via USB with a DATA cable (not charging).
go to https://web.esphome.io/
click ā€œconnectā€
you should see a usb serial device listed for it. pair with it and click getting started (may be called differently). This will download an initial base configuration for ESPhome to the target device. From this point you can attach to wifi. Then in home assistant, the ESPhome builder integration should autodiscover the device. Take control of it then start sending OTA updates

2 Likes

Thanks that worked. It uploaded the base config successfully but then gives an error that the ā€œImprov Wi-Fi Serial not detected.ā€ I unplug/plug in and it says the same thing. I had to go to logs and click ā€œreset deviceā€ then it started up in AP mode. This is a great start, thanks again!

1 Like

It looks like they may have changed the board on the smallTV Pro, am i out of luck here?

I got a few with the same board, its an ESP32. Build your esphome config, then login to the built in web interface and flash the firmware.ota.bin file. Once thats done you can manage it from esphome from them onwards.

You can probably also flash it through those headers too, but I didn’t try.

1 Like