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

My plus arrived today. Will update any progress.

1 Like

I received my Pro today, any further progress on this topic guys ?

Mine is just sitting on my desk telling me the time.

The pro is working fine on my side. The amount of memory available on this one makes it more confortable. I use it as a small monitor to display on different pages (weather forecast, temperature graph, mailbox…) some key information from my HA.

2 Likes

That’s really cool, I was searching for how can I do something similar, Do you mind sharing your ESPHome config file for your setup !!

Implementation is really tied to your HA entities, but In case it could serve your inspiration, here’s what I end up with

Note the native display page feature of ESP Home is not working on this display type. had to rebuild it manually

esphome:
  name: smalltv-esp32
  friendly_name: smalltv_esp32

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

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

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Smalltv-Esp32 Fallback Hotspot"
    password: "NOtnhLeYNfPB"

captive_portal:
    

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



#captive_portal:
debug:
  update_interval: 5s

sensor:
  - platform: homeassistant
    entity_id: sensor.abri_bois_am2301_temperature
    id: abri_bois

  - platform: homeassistant
    entity_id: sensor.atc_mez41e_641e_temperature
    id: mezzanine

  - platform: homeassistant
    entity_id: sensor.piscine_temperature
    id: piscine

  - platform: homeassistant
    entity_id: sensor.atc_sal505_6505_temperature
    id: salon

  - platform: homeassistant
    entity_id: sensor.atc_julb28_3b28_temperature
    id: juliette

  - platform: homeassistant
    entity_id: sensor.atc_vic77a_d77a_temperature
    id: victorien

  - platform: homeassistant
    entity_id: sensor.atc_cle63e_a63e_temperature
    id: clemence

  - platform: homeassistant
    entity_id: sensor.atc_sdb80a_880a_temperature
    id: sdb_etage

  - platform: homeassistant
    entity_id: sensor.atc_cui76c_576c_temperature
    id: cuisine

  - platform: homeassistant
    entity_id: sensor.atc_cab2c2_temperature
    id: cabane_ext

  - platform: homeassistant
    entity_id: sensor.garage_temp
    id: garage

  - platform: homeassistant
    entity_id: sensor.nodered_f80113f7800c75ed
    id: girouette



  - platform: homeassistant
    entity_id: weather.varades
    attribute: pressure
    id: pressure_weather

  - platform: homeassistant
    entity_id: sensor.girouette_pression
    id: pressure

  

  - platform: homeassistant
    name: "T_max_day0"
    entity_id: sensor.T_max_day0
    id: T_max_day0
  - platform: homeassistant
    name: "T_max_day1"
    entity_id: sensor.T_max_day1
    id: T_max_day1
  - platform: homeassistant
    name: "T_max_day2"
    entity_id: sensor.T_max_day2
    id: T_max_day2
  - platform: homeassistant
    name: "T_max_day3"
    entity_id: sensor.T_max_day3
    id: T_max_day3
  - platform: homeassistant
    name: "T_max_day4"
    entity_id: sensor.T_max_day4
    id: T_max_day4

  - platform: homeassistant
    name: "T_min_day0"
    entity_id: sensor.T_min_day0
    id: T_min_day0
  - platform: homeassistant
    name: "T_min_day1"
    entity_id: sensor.T_min_day1
    id: T_min_day1
  - platform: homeassistant
    name: "T_min_day2"
    entity_id: sensor.T_min_day2
    id: T_min_day2
  - platform: homeassistant
    name: "T_min_day3"
    entity_id: sensor.T_min_day3
    id: T_min_day3    
  - platform: homeassistant
    name: "T_min_day4"
    entity_id: sensor.T_min_day4
    id: T_min_day4  

  - platform: homeassistant
    name: "Precipitation_day0"
    entity_id: sensor.Precipitation_day0
    id: Precipitation_day0
  - platform: homeassistant
    name: "Precipitation_day1"
    entity_id: sensor.Precipitation_day1
    id: Precipitation_day1
  - platform: homeassistant
    name: "Precipitation_day2"
    entity_id: sensor.Precipitation_day2
    id: Precipitation_day2
  - platform: homeassistant
    name: "Precipitation_day3"
    entity_id: sensor.Precipitation_day3
    id: Precipitation_day3    
  - platform: homeassistant
    name: "Precipitation_day4"
    entity_id: sensor.Precipitation_day4
    id: Precipitation_day4   

  - platform: homeassistant
    name: "index_day0"
    entity_id: sensor.index_day0
    id: index_day0

    

text_sensor:
  - platform: homeassistant
    name: "Condition_day0"
    entity_id: sensor.Condition_day0
    id: Condition_day0
  - platform: homeassistant
    name: "Condition_day1"
    entity_id: sensor.Condition_day1
    id: Condition_day1
  - platform: homeassistant
    name: "Condition_day2"
    entity_id: sensor.Condition_day2
    id: Condition_day2
  - platform: homeassistant
    name: "Condition_day3"
    entity_id: sensor.Condition_day3
    id: Condition_day3        
  - platform: homeassistant
    name: "Condition_day4"
    entity_id: sensor.Condition_day4
    id: Condition_day4   


# Define a PWM output on the ESP32
output:
  - platform: ledc
    pin: GPIO25
    inverted: True
    id: backlight_pwm
  - platform: ledc
    pin: GPIO12
    id: rtttl_out

rtttl:
  output: rtttl_out

# Define a monochromatic, dimmable light for the backlight
light:
  - platform: monochromatic
    output: backlight_pwm
    name: "Display Backlight"
    id: back_light
    restore_mode: ALWAYS_ON


esp32_touch:
 # setup_mode: true


globals:
- id: page
  type: int
  initial_value: "1"

interval:
  - interval: 20s
    then:
      - lambda: |-
          /*
          id(page) = (id(page) + 1);
          if (id(page) > 3) {
            id(page) = 1;
          } */


binary_sensor:

  - platform: homeassistant
    entity_id: binary_sensor.status_porte_garage
    id: porte_garage

  - platform: homeassistant
    entity_id: binary_sensor.portail_lock_sense
    id: portail  
  - platform: esp32_touch
    name: "ESP32 Touch Pad GPIO32"
    pin: GPIO32
    threshold: 1250
    id: gp32
    on_click:
    - min_length: 50ms
      max_length: 350ms
      then:
        - if:
            condition:
            - light.is_off: back_light
            then:
            - light.turn_on: 
                id: back_light
            else:
              - lambda: |-
                    id(page) = (id(page) + 1);
                    if (id(page) > 3) {
                      id(page) = 1;
                    }
              - component.update : disp

    - min_length: 1000ms
      max_length: 2000ms
      then:
        - light.turn_off: back_light
        - rtttl.play: 'two_short:d=4,o=5,b=100:16e6,16e6'

  - platform: esp32_touch
    name: "ESP32 Touch Pad GPIO33"
    pin: GPIO33
    threshold: 1375
    id: gp33
    on_click:
    - min_length: 50ms
      max_length: 350ms
      then:

        - if:
            condition:
            - light.is_off: back_light
            then:
            - light.turn_on: 
                id: back_light
            else:
              - lambda: |-
                    id(page) = (id(page) - 1);
                    if (id(page) < 1) {
                      id(page) = 3;
                    } 
              - component.update : disp
    - min_length: 1000ms
      max_length: 2000ms
      then:
        - light.turn_off: back_light


number:
  - platform: template
    name: "disp page"
    optimistic: true
    min_value: 0
    max_value: 4
    step: 1
    on_value:
      then:
        - lambda: |-
            id(page) = x;
        - component.update : disp



font:
  - file: 'OpenSans-Regular.ttf'
    id: font20
    size: 20

  - file: 'OpenSans-Regular.ttf'
    id: font60
    size: 50

  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: fonticon
    size: 50
    glyphs: &mdi-weather-glyphs
      - "\U000F0590" # mdi-weather-cloudy
      - "\U000F0F2F" # mdi-weather-cloudy-alert
      - "\U000F0E6E" # mdi-weather-cloudy-arrow-right
      - "\U000F0591" # mdi-weather-fog
      - "\U000F0592" # mdi-weather-hail
      - "\U000F0F30" # mdi-weather-hazy
      - "\U000F0898" # mdi-weather-hurricane
      - "\U000F0593" # mdi-weather-lightning
      - "\U000F067E" # mdi-weather-lightning-rainy
      - "\U000F0594" # mdi-weather-night
      - "\U000F0F31" # mdi-weather-night-partly-cloudy
      - "\U000F0595" # mdi-weather-partly-cloudy
      - "\U000F0F32" # mdi-weather-partly-lightning
      - "\U000F0F33" # mdi-weather-partly-rainy
      - "\U000F0F34" # mdi-weather-partly-snowy
      - "\U000F0F35" # mdi-weather-partly-snowy-rainy
      - "\U000F0596" # mdi-weather-pouring
      - "\U000F0597" # mdi-weather-rainy
      - "\U000F0598" # mdi-weather-snowy
      - "\U000F0F36" # mdi-weather-snowy-heavy
      - "\U000F067F" # mdi-weather-snowy-rainy
      - "\U000F0599" # mdi-weather-sunny
      - "\U000F0F37" # mdi-weather-sunny-alert
      - "\U000F14E4" # mdi-weather-sunny-off
      - "\U000F059A" # mdi-weather-sunset
      - "\U000F059B" # mdi-weather-sunset-down
      - "\U000F059C" # mdi-weather-sunset-up
      - "\U000F0F38" # mdi-weather-tornado
      - "\U000F059D" # mdi-weather-windy
      - "\U000F059E" # mdi-weather-windy-variant
      - "\U000F058C" # mdi-water
      - "\U000F17FB" # mdi-GarageLock
      - "\U000F06DA" # mdi-GarageOpen      
      - "\U000F116A" # mid-GateOpen
      - "\U000F0299" # mdi-GateClose
      - "\U000F06EE" # mdi-mailbox
      - "\U000F0A79" # mdi-trash-can
      - "\U000F001B" # mdi-Air-conditioner
      - "\U000F0D91" # mdi-MotionSensor-ON
      - "\U000F1435" # mdi-MotionSensor-Off

  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: fonticon20
    size: 20
    glyphs: &mdi-weather-glyphs20
      - "\U000F058C" # mdi-water
      - "\U000F005C" # mdi-ArrowTopRight
      - "\U000F0043" # mdi-ArrowBottomRight"
      - "\U000F092B" # no-wifi
      - "\U000F092F" # low-wifi
      - "\U000F091F" # wifi-1
      - "\U000F0922" # wifi-2
      - "\U000F0925" # wifi-3
      - "\U000F0928" # wifi-4

color:
    - id: color_green
      red: 0%
      green: 100%
      blue: 0%
    - id: color_red
      red: 100%
      green: 0%
      blue: 0%
    - id: color_blue
      red: 0%
      green: 0%
      blue: 100%
    - id: color_orange
      red: 100%
      green: 64%
      blue: 0%

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO23
  interface: hardware
  id: spihwd

graph:

  - id: pressure_graph
    sensor: pressure
    duration: 24h
    width: 180
    height: 100
    color: color_orange
  - id: multi_temperature_graph
    duration: 24h
    width: 180
    height: 100
    traces:
      - sensor: abri_bois
        line_type: DOTTED
        color: color_blue
      - sensor: salon
        line_type: SOLID
        color: color_green

  

display:
  - platform: st7789v
    model: "Custom"
    spi_id: spihwd
    height: 240
    width: 240
    offset_height: 0
    offset_width: 0
    dc_pin: GPIO02
    reset_pin: GPIO04
    #backlight_pin: GPIO25
    eightbitcolor: True
    #update_interval: never
    update_interval: 5s
    id: disp


    lambda: |-
          int y;
          int x;

          //--------------------------------------------------------------------------
          // Map weather states to MDI characters.
          //--------------------------------------------------------------------------
          std::map<std::string, std::string> weather_icon_map
            {
              {"cloudy", "\U000F0590"},
              {"cloudy-alert", "\U000F0F2F"},
              {"cloudy-arrow-right", "\U000F0E6E"},
              {"fog", "\U000F0591"},
              {"hail", "\U000F0592"},
              {"hazy", "\U000F0F30"},
              {"hurricane", "\U000F0898"},
              {"lightning", "\U000F0593"},
              {"lightning-rainy", "\U000F067E"},
              {"night", "\U000F0594"},
              {"clear-night", "\U000F0594"},
              {"night-partly-cloudy", "\U000F0F31"},
              {"partlycloudy", "\U000F0595"},
              {"partly-lightning", "\U000F0F32"},
              {"partly-rainy", "\U000F0F33"},
              {"partly-snowy", "\U000F0F34"},
              {"partly-snowy-rainy", "\U000F0F35"},
              {"pouring", "\U000F0596"},
              {"rainy", "\U000F0597"},
              {"snowy", "\U000F0598"},
              {"snowy-heavy", "\U000F0F36"},
              {"snowy-rainy", "\U000F067F"},
              {"sunny", "\U000F0599"},
              {"sunny-alert", "\U000F0F37"},
              {"sunny-off", "\U000F14E4"},
              {"sunset", "\U000F059A"},
              {"sunset-down", "\U000F059B"},
              {"sunset-up", "\U000F059C"},
              {"tornado", "\U000F0F38"},
              {"windy", "\U000F059D"},
              {"windy-variant", "\U000F059E"},
            };

          std::string weekdays[7]={"Lun","Mar","Mer","Jeu","Ven","Sam","Dim"};


          switch (id(page)){

            default:
            case 0:
            case 1:
              it.printf(0, 0, id(font60),  "%.1f°",id(abri_bois).state);
              if (id(Precipitation_day0).state) {
                it.printf(130, 5, id(fonticon20), id(color_blue),"\U000F058C");
                it.printf(145, 0, id(font20), id(color_blue),"%.0f",id(Precipitation_day0).state);
              }
              it.printf(130, 20, id(font20), id(color_red), "%.0f°",id(T_max_day0).state);
              it.printf(130, 40, id(font20), id(color_green), "%.0f°",id(T_min_day0).state);
              it.printf(190, 20, id(fonticon), "%s", weather_icon_map[id(Condition_day0).state.c_str()].c_str());

              it.printf(0, 60, id(font20), id(color_orange), "%.0fhPa",id(pressure).state);

              // Days name for forecast
              y = 100;
              x = 5; 
              it.printf(x, y, id(font20), "%s", weekdays[(int)(id(index_day0).state+1)%7].c_str());
              x += 60;
              it.printf(x, y, id(font20), "%s", weekdays[(int)(id(index_day0).state+2)%7].c_str());
              x += 60;
              it.printf(x, y, id(font20), "%s", weekdays[(int)(id(index_day0).state+3)%7].c_str());
              x += 60;
              it.printf(x, y, id(font20), "%s", weekdays[(int)(id(index_day0).state+4)%7].c_str());

              //Forecast 

              // Day +1
              y = 122;
              x = 5;
              it.printf(x, y, id(fonticon), "%s", weather_icon_map[id(Condition_day1).state.c_str()].c_str());
              it.printf(x, y+40, id(font20), id(color_red), "%.0f°",id(T_max_day1).state);
              it.printf(x, y+60, id(font20), id(color_green), "%.0f°",id(T_min_day1).state);
              if (id(Precipitation_day1).state) {
                it.printf(x, y+85, id(fonticon20), id(color_blue),"\U000F058C");
                it.printf(x+15, y+80, id(font20), id(color_blue),"%.0f",id(Precipitation_day1).state);
              }

              // Day + 2
              x += 60;
              it.printf(x, y, id(fonticon), "%s", weather_icon_map[id(Condition_day2).state.c_str()].c_str());
              it.printf(x, y+40, id(font20), id(color_red), "%.0f°",id(T_max_day2).state);
              it.printf(x, y+60, id(font20), id(color_green), "%.0f°",id(T_min_day2).state);
              if (id(Precipitation_day2).state) {
                it.printf(x, y+85, id(fonticon20), id(color_blue),"\U000F058C");
                it.printf(x+15, y+80, id(font20), id(color_blue),"%.0f",id(Precipitation_day2).state);
              }

              // Day + 3
              x += 60;
              it.printf(x, y, id(fonticon), "%s", weather_icon_map[id(Condition_day3).state.c_str()].c_str());
              it.printf(x, y+40, id(font20), id(color_red), "%.0f°",id(T_max_day3).state);
              it.printf(x, y+60, id(font20), id(color_green), "%.0f°",id(T_min_day3).state);
              if (id(Precipitation_day3).state) {
                it.printf(x, y+85, id(fonticon20), id(color_blue),"\U000F058C");
                it.printf(x+15, y+80, id(font20), id(color_blue),"%.0f",id(Precipitation_day3).state);
              }

              // Day + 4
              x += 60;
              it.printf(x, y, id(fonticon), "%s", weather_icon_map[id(Condition_day4).state.c_str()].c_str());
              it.printf(x, y+40, id(font20), id(color_red), "%.0f°",id(T_max_day4).state);
              it.printf(x, y+60, id(font20), id(color_green), "%.0f°",id(T_min_day4).state);
              if (id(Precipitation_day4).state) {
                it.printf(x, y+85, id(fonticon20), id(color_blue),"\U000F058C");
                it.printf(x+15, y+80, id(font20), id(color_blue),"%.0f",id(Precipitation_day4).state);
              }
              break;

            case 2:
              x = 5;
              y = 0;

              it.printf(x, y, id(font20),  "Abri");
              it.printf(x, y+20, id(font20), "%.1f°",id(abri_bois).state);
              x += 60;
              it.printf(x, y, id(font20),  "CabE.");
              it.printf(x, y+20, id(font20), "%.1f°",id(cabane_ext).state);
              x += 60;
              it.printf(x, y, id(font20),  "Gir.");
              it.printf(x, y+20, id(font20), "%.1f°",id(girouette).state);
              x += 60;
              it.printf(x, y, id(font20),  "Pisc.");
              it.printf(x, y+20, id(font20), "%.1f°",id(piscine).state);


              x = 5;
              y = 50;
              it.printf(x, y, id(font20),  "Juju");
              it.printf(x, y+20, id(font20), "%.1f°",id(juliette).state);
              x += 60;
              it.printf(x, y, id(font20),  "Clem");
              it.printf(x, y+20, id(font20), "%.1f°",id(clemence).state);
              x += 60;
              it.printf(x, y, id(font20),  "Vict");
              it.printf(x, y+20, id(font20), "%.1f°",id(victorien).state);
              x += 60;
              it.printf(x, y, id(font20),  "Sdb Et.");
              it.printf(x, y+20, id(font20), "%.1f°",id(sdb_etage).state);


              x = 5;
              y = 100;
              it.printf(x, y, id(font20),  "Mezz");
              it.printf(x, y+20, id(font20), "%.1f°",id(mezzanine).state);
              x += 60;
              it.printf(x, y, id(font20),  "Salon");
              it.printf(x, y+20, id(font20), "%.1f°",id(salon).state);
              x += 60;
              it.printf(x, y, id(font20),  "Cuis.");
              it.printf(x, y+20, id(font20), "%.1f°",id(cuisine).state);
              x += 60;
              it.printf(x, y, id(font20),  "Garge");
              it.printf(x, y+20, id(font20), "%.1f°",id(garage).state);

              x = 5;
              y = 150;
              it.printf(x, y, id(font20),  "Garge");
              if (id(porte_garage).state) {
                it.printf(x, y+20, id(fonticon),id(color_green), "\U000F06DA"); // Open
              } else {
                it.printf(x, y+20, id(fonticon),id(color_red), "\U000F17FB"); // Lock
              }
              x += 60;
              it.printf(x, y, id(font20),  "Portail");
              if (id(portail).state) {
                it.printf(x, y+20, id(fonticon),id(color_green), "\U000F116A"); // Gate Open
              } else {
                it.printf(x, y+20, id(fonticon),id(color_red), "\U000F0299"); // Gate Lock
              }


              break;

            case 3:
              
              it.graph(0, 0, id(pressure_graph));
              it.printf(190, 0, id(font20), id(color_orange), "%.0f",id(pressure).state);
              it.printf(190, 20, id(font20), id(color_orange), "hPa");


              it.graph(0, 120, id(multi_temperature_graph));
              it.printf(190, 120, id(font20), id(color_blue),  "Ext");
              it.printf(190, 140, id(font20), id(color_blue),  "%.1f°",id(abri_bois).state);

              it.printf(190, 160, id(font20), id(color_green),  "Int");
              it.printf(190, 180, id(font20), id(color_green),  "%.1f°",id(salon).state);
              break;


          }



9 Likes

Hello! Interesting topic! :star_struck:
I ask for a feature request which it can be helpful and funny as well. Please have a look and if you find it interesting or you have better suggestions please to vote or add a comment. :wink:

Well you don’t need that now do you. Just use esphome

1 Like

Answered my own question: see below.

How are you guys flashing these devices? I have SmallTV Pro (so the esp32 device). When I plug it into USB of the esphome server (a linux x86 box) or into my windows laptop it doesn’t seem to register a serial device. (Using the same cable etc I can see other devices).

Do I perhaps have to disassemble it and plug a flasher device in? I haven’t had to do that in a while. Or perhaps the original firmware can upload an esphome firmware vis OTA in some fashion?

Tips appreciated :slight_smile:

Here is how - if you compile the firmware on esphome and download the bin file in legacy format it can be flashed using the inbuilt firmware updater on the SmallTV Pro.

2 Likes

Just a heads up on @rletendu’s code for the display. I have been playing around over the last couple of days using esphome 2023.12.5 and home assistant 2024.1.0b3 (yes the dreaded beta test version).

esphome 2023.12.5 does not seem to work on @rletendu’s github code, and after reading this PR st7789 using mode3 when no cs pin by rletendu · Pull Request #5541 · esphome/esphome · GitHub I realised that the spi change should be done in the config of the st7789v component in your esphome yaml. In other words, take out the external_component code from what @rletendu’s config in Post 34 above and use this in the display code

display:
  - platform: st7789v
    model: "Custom"
    spi_id: spihwd
    height: 240
    width: 240
    offset_height: 0
    offset_width: 0
    dc_pin: GPIO02
    reset_pin: GPIO04
    #backlight_pin: GPIO25
    eightbitcolor: True
    #update_interval: never
    update_interval: 5s
    id: disp
    spi_mode: mode3

The change is the last line spi_mode: mode3

Hope that helps someone, my device now at least says “Hello World” :slight_smile:

PS no detraction from @rletendu’s work, he worked out the problems and did all the work. I think esphome changed the rules of engagement :slight_smile:

Hello, sorry for my english. Have you the good code for use this module with this screen ?
Thank you

Read the thread, he posted the code, but also see my recent updating post.

Hello, i try you’re code but i have the code error:
ValueError: Component ID st7789v_st7789v was not declared to inherit from Component, or was registered twice. Please create a bug report with your configuration.
when i put you’re repo.

See Installing ESPhome on GEEKMAGIC Smart Weather Clock (smalltv/pro) - #38 by nickrout

Sorry, but i don’t understand why don’t work.
There is the code for test:

esphome:
  name: test
  friendly_name: test
  comment: Living room ESP32 controller
  area: Living Room

esp8266:
  board: esp12e
 
# Enable logging
logger:

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

ota:
  password: ""

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

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

captive_portal:

time:
  - platform: homeassistant
    id: homeassistant_time

font:
  - file: 'fonts/OpenSans-Regular.ttf'
    id: font1
    size: 30

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

sensor:

  # Uptime sensor
  - platform: uptime
    name: "Uptime"

  # WiFi Signal sensor
  - platform: wifi_signal
    name: "WiFi Signalstärke"
    update_interval: 60s

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

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

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



display:
  - platform: st7789v
    model: "Custom"
    spi_id: spihwd
    height: 240
    width: 240
    offset_height: 0
    offset_width: 0
    dc_pin: GPIO02
    reset_pin: GPIO04
    #backlight_pin: GPIO25
    eightbitcolor: True
    #update_interval: never
    update_interval: 5s
    id: disp
    spi_mode: mode3
    lambda: |-
      it.printf(0, 0, id(font1), id(color_green),"Test1");
      it.printf(1, 1, id(font1), id(color_green),"Test2");
      it.printf(10, 10, id(font1), id(color_green),"Test3");
      it.printf(100, 100, id(font1), id(color_green),"Test4");
      

I have a esp8266 whith lcd 10 pin
The screen on but not display.
Thank you, for you’re help, it’s very nice :wink:

Hi,

Latest ESP Home releases with “spi_mode : mode3” in display configuration will work with ESP32 but not with ESP8266 which is still suffering for hwd RAM limitation preventing frame buffer usage.
Some latest changes in ESPHome are not compatible with my previous fork branch that allowed to skip frame buffer usage and allows esp8266 with ST7789. I need to work on this.

Okay, thanks for all your work :slight_smile: . I await your return on the subject.

Hello,
i test ok on arduino
whith this code:

#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>

#define TFT_DC    0    
#define TFT_RST   2 
#define TFT_CS    5  
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

void setup() {
  Serial.begin(9600);
  Serial.print(F("Connexion ok"));
  tft.init(240, 240, SPI_MODE2); 
  tft.setRotation(2);
 
  tft.fillScreen(ST77XX_BLACK);
  testdrawtext("Hello Word", ST77XX_WHITE);
  
}

void testdrawtext(char *text, uint16_t color) {
  tft.setTextSize(3);
  tft.setCursor(0, 0);
  tft.setTextColor(color);
  tft.setTextWrap(true);
  tft.print(text);
}


void loop() {

}

you can use this work for esphome it’s ok for the screen.

Hi,

I have created an update esphome branch for ST7789v and ESP8266 compatible with esphome 202312 release

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

together the spi mode option

spi_mode : mode3

This allows the no pro version of the Geekmagic gadget to work.

For the pro version with esp32 SOC the default latest esphome with appropriate spi mode3 option is working out of the box.

5 Likes

I’ve just received a smalltvpro direct from geekmagic and just wanted to thankyou all for the work on this. (ordered two but the other is the 8266 variant :-/ )

It is a nice small display in a box and after first updating it to their own newest firmware i followed the instructions in this thread and now i have it showing the time from ESPhome

Time to customize - pun intended :slight_smile:

2 Likes