EPShome timezone issues

My esphome device with HA sourced time seems to not have control over which timezone is used. If I leave timezone: out of the config, it usually just displays UTC. Adding timezone into the config as shown results in the correct time for a short time after reboot, then it reverts to showing UTC after a while:

substitutions:
  name: "test_wemos"
  friendly_name: "Test Wemos"

esphome:
  name: ${name}
  platform: ESP8266
  board: nodemcuv2

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${friendly_name} Fallback Hotspot"
    password: "password"

captive_portal:

logger:

api:
  password: !secret test_wemos_password
# Enable ota
ota:
  password: !secret ota_password

# Device Specific Configs ###########################################
# Test Wemos D1 Mini board
# Built In LED = GPIO2
# GPIO13 = D7

# SSD1306 Configs
time:
  - platform: homeassistant
    timezone: "America/Los_Angeles"
    id: ha_time
mqtt:
  broker: 192...
  username: !secret mqtt_client_user1
  password: !secret mqtt_client_pass1
font:
  - file: "verdana.ttf"
    id: my_fontlg
    size: 18
  - file: "verdana.ttf"
    id: my_fontsm
    size: 14
i2c:
  sda: D1
  scl: D2
display:
  - platform: ssd1306_i2c
    id: my_display
    pages:
      - id: page1
        lambda: |-
          it.strftime(0, 0, id(my_fontlg), "%I:%M:%S %p", id(ha_time).now());
          it.strftime(0, 20, id(my_fontlg), "%a, %b %d", id(ha_time).now());
          it.printf(0, 55, id(my_fontlg), "BckYd: %.1f F", id(backyard_temp).state);
          if (id(button).state) {
            it.line(0, 63, 127, 63);
          }
      - id: page2
        lambda: |-
          it.strftime(0, 5, id(my_fontlg), "%I:%M:%S %p", id(ha_time).now());
          it.strftime(0, 25, id(my_fontlg), "%m-%d-%Y", id(ha_time).now());
          if (id(button).state) {
            it.line(0, 63, 127, 63);
          }
    model: "SSD1306 128x64"
    reset_pin: D0
    address: 0x3C
interval:
  - interval: 5s
    then:
      - display.page.show_next: my_display
      - component.update: my_display
      
# DFplayer configs
uart:
  tx_pin: D5
  rx_pin: D6
  baud_rate: 9600

# Declare DFPlayer mini module
dfplayer:
  on_finished_playback:
    then:
      logger.log: 'Somebody press play!'
      
# Generic configs
binary_sensor:
  - platform: status
    name: "${friendly_name} Status"
    
  - platform: gpio
    pin:
      number: GPIO13
      mode: INPUT_PULLUP
      inverted: true
    name: "${friendly_name} Button"
    id: button
    filters:
      - delayed_on: 10ms
      - delayed_off: 10ms
    on_press:
      then:
        - switch.turn_on: led
        - dfplayer.set_volume: 25
        - delay: 150ms
        - dfplayer.play_next:
    on_release:
      then:
        - switch.turn_off: led

#status_led:
#  pin: GPIO2
  
sensor:
  - platform: wifi_signal
    name: "${friendly_name} WiFi Signal"
    update_interval: 60s
    
  - platform: mqtt_subscribe
    name: "Backyard Temperature"
    id: backyard_temp
    topic: esphome/backyard_temp
    
switch:
  - platform: gpio
    name: "${friendly_name} LED"
    pin: GPIO2
    id: led
    inverted: true

Not sure if I’m just trippin’, but I swear this problem didn’t happen until after I added in the dfplayer stuff. Everything else in this test code is working as expected. I’m guessing there just some simple error in my config. Any help getting timezones working reliably here is greatly appreciated.

Anyone? I tried again without the timezone in the config, and it does the same thing. Correct time at first, but at some point it reverts to and stays on UTC.

One possibility is that at some point your chip is losing connection with the network. Since you have captive portal in your code that may reset timezone to utc. That may explain why it works for a while and then magically changes to utc. Just a guess.

BTW every time you call now() the system does a lot of gymnastics to recreate the ESPTIME structure. Might be better to do it once at the top of the lambda, save it, and reuse it. Probably not a big deal but…

Thanks for the suggestion, I will try removing captive portal and see how it goes.

Also thanks for the heads up on repeated use of now(). I am more familiar with how to optimize code in C/C++, but still very clunky when it comes to python. I’ll look into saving the results to minimize that call.

Unfortunately, removing the captive portal parts didn’t fix it. So this ‘magic’ isn’t coming from there. :wink:

Hmmm… Well the system timestamp will be in utc time. The procedure now() calls the cpp library time() to get the utc timestamp and localtime() to convert the timestamp to local time using the timezone information. The result is then stored in the ESPTIME structure which allows you to display local time to the user. So that would seem to imply that something is changing the saved timezone information. I suppose you could print out the timezone to verify that.

Solved it… turns out the time sync gets lost if you don’t actually add the integration to HA. This was a test device, so I was just playing with it ‘externally’, and never actually clicked on the esphome integration to add it. I am still wondering how it initially gets the proper time, and for that matter shows the API logging, if it’s not ‘connected enough’ to sync time later on.

Anyhow, I ran several experiments to verify this behavior. Now I can saw fairly certainly, that if you use platform: homeassistant in for time in esphome, it will initially sync (good for testing purposes) but soon will go out of sync. The time won’t stay in sync unless you add the integration to HA.

For me, UTC-3 didn´t work, but Timezone: UTC−03:00 solves de issue.

1 Like