Esphome - Time .now().timestamp updating every 128 seconds instead of every 1 second?

Hi

I’m having a hard time getting proper timestamp, it only updates after exactly 128 seconds, all-through it should update every seconds, at least I hope this is what my code is doing. When using .seconds it updates properly.

time:
  - platform: homeassistant
    id: hastime


interval:
  - interval: 1s
    then:
      - lambda: |-
          if (id(hastime).utcnow().is_valid()) {
            id(timestamp_sec).publish_state(id(hastime).utcnow().timestamp);
            id(time_seconds).publish_state(id(hastime).utcnow().second);
          }

sensor: 

  - platform: template
    name: "Current time stamp"
    id: timestamp_sec
  
  - platform: template
    name: "Current time"
    id: time_seconds

Here is part of the the output when the timestamp finally updates.

[21:43:24][D][sensor:092]: 'Current time': Sending state 24.00000  with 1 decimals of accuracy
[21:43:25][D][sensor:092]: 'Current time stamp': Sending state 1584927744.00000  with 1 decimals of accuracy
[21:43:25][D][sensor:092]: 'Current time': Sending state 25.00000  with 1 decimals of accuracy
[21:43:26][D][sensor:092]: 'Current time stamp': Sending state 1584927744.00000  with 1 decimals of accuracy
[21:43:26][D][sensor:092]: 'Current time': Sending state 26.00000  with 1 decimals of accuracy
[21:43:27][D][sensor:092]: 'Current time stamp': Sending state 1584927744.00000  with 1 decimals of accuracy
[21:43:27][D][sensor:092]: 'Current time': Sending state 27.00000  with 1 decimals of accuracy
[21:43:28][D][sensor:092]: 'Current time stamp': Sending state 1584927744.00000  with 1 decimals of accuracy
[21:43:28][D][sensor:092]: 'Current time': Sending state 28.00000  with 1 decimals of accuracy
[21:43:29][D][sensor:092]: 'Current time stamp': Sending state 1584927872.00000  with 1 decimals of accuracy
[21:43:29][D][sensor:092]: 'Current time': Sending state 29.00000  with 1 decimals of accuracy
[21:43:30][D][sensor:092]: 'Current time stamp': Sending state 1584927872.00000  with 1 decimals of accuracy
[21:43:30][D][sensor:092]: 'Current time': Sending state 30.00000  with 1 decimals of accuracy
[21:43:31][D][sensor:092]: 'Current time stamp': Sending state 1584927872.00000  with 1 decimals of accuracy
[21:43:31][D][sensor:092]: 'Current time': Sending state 31.00000  with 1 decimals of accuracy
[21:43:32][D][sensor:092]: 'Current time stamp': Sending state 1584927872.00000  with 1 decimals of accuracy
1 Like

I am also facing same issue

ESPHome uses floats (4 bytes) not doubles (8 bytes) to represent sensor states. The number of digits that can be represented with floats is not sufficient for timestamps. Hence the value seems to jump in steps of 128 (quantization).

The result of utcnow() is in fact a signed int, which can hold all the precision that you need. So any timestamp calculations within your lambda will be correct as long as you don’t convert to float. But you implicitly convert to float when you call publish_state().

I am not an expert in C++ but you could try and use a bit mask to show that the int value of a timestamp changes with each second. Something like…

id(timestamp_sec).publish_state(id(hastime).utcnow().timestamp & 1)

Tip:
Try to use millis() if you need something that increases every millisecond but has a base value that will fit into a float.

thanks for reply.
how do i get gps timestamp in home assistant?

Just from the back of my mind and without testing:

  1. Publish the Unix epoche timestamp in seconds, not in milliseconds.
  2. Make sure to correctly set the device_class of your sensor:
    device_class: "timestamp"

Something like:

interval:
  - interval: 1s
    then:
      - lambda: |-
          if (id(hastime).utcnow().is_valid()) {
            id(timestamp_sec).publish_state(id(hastime).utcnow().timestamp / 1000);
          }

sensor: 
  - platform: template
    name: "Current time stamp"
    id: timestamp_sec
    device_class: "timestamp"

UPDATE:
Attention! I was very wrong about the seconds! HA in fact expects timestamp sensors in milliseconds. And there seems to be no way around the fact that the Unix epoch values, measured in milliseconds, are to big for C++ floats to store all digits. So you lose some precision when the timestamps arrive in HA (about +/-64 seconds). See below…

thanks for help .
i test it but not ok.
yyyy

“51 years ago” means 01.01.1970 – the start of the Unix epoche.
You obviously published 0 (zero) into your timestamp sensor.
What does your ESPHome log tell you?

  
  
  textname: templatexx
#globals:
#   - id: timestamp_sec
#     type: int  
#    restore_value: no
#    initial_value: '0' 
#   - id: my_vmin_int
#     type: float
#     restore_value: no
#     initial_value: '250'   



esphome:
  name: esp321
  platform: ESP32
  board: lolin32

wifi:
  ssid: "Mi wifi"
  password: "behnam123"
  
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp321 Fallback Hotspot"
    password: "coCKxLsID1nI"

captive_portal:

# Enable logging
logger: 
  level: debug

# 6Enable Home Assistant API
api:
ota:

uart:
  rx_pin: 32
  baud_rate: 9600
##########################################

  

  
  
  
  
  
  

# Declare GPS module
gps:
  latitude:
    name: "Latitude"
  longitude:
    name: "Longitude"
  altitude:
    name: "Altitude"
    id: a

# GPS as time source
time:
  - platform: gps
    id: gps_time
    
    on_time:
      - seconds: '*'
        then: 
          - lambda: |-
#             ESP_LOGI("gps", "%02d:%02d:%02d:%08d",id(gps_time).now().hour, id(gps_time).now().minute, id(gps_time).now().second,id(gps_time).now().timestamp);
#          - ESP_LOGI("gphs","%02d-%02d-%02d %02d:%02d:%02d",  id(gps_time).now().timestamp);
#             ESP_LOGI("gps1" , "%02d-%02d-%02d %02d:%02d:%02d", id(gps_time).now().year, id(gps_time).now().month, id(gps_time).now().day_of_month, id(gps_time).now().hour, id(gps_time).now().minute, id(gps_time).now().second);             

          - sensor.template.publish:
             id: template_sens
             state: !lambda
                return id(gps_time).now().timestamp;
          - text_sensor.template.publish:
             id: last_bell_press
             state: !lambda |-
                char str[20];
                time_t currTime = id(gps_time).now().timestamp;
                strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", localtime(&currTime));
                return  { str };

interval:
  - interval: 1s
    then:
      - lambda: |-
          if (id(gps_time).utcnow().is_valid()) {
            id(timestamp_sec).publish_state(id(gps_time).utcnow().timestamp /1000 );
          }

sensor: 
  - platform: template
    name: "Current time stamp"
    id: timestamp_sec
    device_class: "timestamp"

    
  - platform: template
    name: "Template Sensor"
    id: template_sens
    accuracy_decimals: 0
#    force_update: true
    update_interval: 1s  
#    device_class: timestamp
#######################################
text_sensor:
  - platform: template
    name: "Template Text Sensor"
    id: last_bell_press

INFO Reading configuration /config/esphome/esp321.yaml…
INFO Detected timezone ‘Asia/Tehran’
INFO Starting log output from esp321.local using esphome API
INFO Successfully connected to esp321.local
[14:45:18][I][app:099]: ESPHome version 2021.10.3 compiled on Nov 3 2021, 14:42:18
[14:45:18][C][wifi:490]: WiFi:
[14:45:18][C][wifi:352]: Local MAC: AC:67:B2:38:79:3C
[14:45:18][C][wifi:353]: SSID: [redacted]
[14:45:18][C][wifi:354]: IP Address: 192.168.2.20
[14:45:18][C][wifi:356]: BSSID: [redacted]
[14:45:18][C][wifi:357]: Hostname: ‘esp321’
[14:45:18][C][wifi:359]: Signal strength: -34 dB ▂▄▆█
[14:45:18][C][wifi:363]: Channel: 2
[14:45:18][C][wifi:364]: Subnet: 255.255.255.0
[14:45:18][C][wifi:365]: Gateway: 192.168.2.5
[14:45:18][C][wifi:366]: DNS1: 1.1.1.1
[14:45:18][C][wifi:367]: DNS2: 8.8.8.8
[14:45:18][C][uart.arduino_esp32:105]: UART Bus:
[14:45:18][C][uart.arduino_esp32:107]: RX Pin: GPIO32
[14:45:18][C][uart.arduino_esp32:109]: RX Buffer Size: 256
[14:45:18][C][uart.arduino_esp32:111]: Baud Rate: 9600 baud
[14:45:18][C][uart.arduino_esp32:112]: Data Bits: 8
[14:45:18][C][uart.arduino_esp32:113]: Parity: NONE
[14:45:18][C][uart.arduino_esp32:114]: Stop bits: 1
[14:45:18][D][gps:040]: Location:
[14:45:18][D][gps:041]: Lat: 38.436832
[14:45:18][D][gps:042]: Lon: 45.778122
[14:45:18][D][gps:047]: Speed:
[14:45:18][D][gps:048]: 0.074080 km/h
[14:45:18][D][gps:052]: Course:
[14:45:18][D][gps:053]: 0.000000 °
[14:45:18][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:18][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:18’
[14:45:18][D][sensor:113]: ‘Current time stamp’: Sending state 1635938.00000 with 1 decimals of accuracy
[14:45:18][D][gps:040]: Location:
[14:45:18][D][gps:041]: Lat: 38.436832
[14:45:18][D][gps:042]: Lon: 45.778122
[14:45:18][D][gps:057]: Altitude:
[14:45:18][D][gps:058]: 1336.400024 m
[14:45:18][D][gps:062]: Satellites:
[14:45:18][D][gps:063]: 7
[14:45:18][C][template.sensor:023]: Template Sensor ‘Current time stamp’
[14:45:18][C][template.sensor:023]: Device Class: ‘timestamp’
[14:45:18][C][template.sensor:023]: State Class: ‘’
[14:45:18][C][template.sensor:023]: Unit of Measurement: ‘’
[14:45:18][C][template.sensor:023]: Accuracy Decimals: 1
[14:45:18][C][template.sensor:024]: Update Interval: 60.0s
[14:45:18][C][template.sensor:023]: Template Sensor ‘Template Sensor’
[14:45:18][C][template.sensor:023]: State Class: ‘’
[14:45:18][C][template.sensor:023]: Unit of Measurement: ‘’
[14:45:18][C][template.sensor:023]: Accuracy Decimals: 0
[14:45:18][C][template.sensor:024]: Update Interval: 1.0s
[14:45:18][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:18][C][template.text_sensor:021]: Template Sensor ‘Template Text Sensor’
[14:45:18][C][logger:233]: Logger:
[14:45:18][C][logger:234]: Level: DEBUG
[14:45:18][C][logger:235]: Log Baud Rate: 115200
[14:45:18][C][logger:236]: Hardware UART: UART0
[14:45:18][C][captive_portal:150]: Captive Portal:
[14:45:18][C][ota:082]: Over-The-Air Updates:
[14:45:18][C][ota:083]: Address: esp321.local:3232
[14:45:18][C][api:134]: API Server:
[14:45:18][C][api:135]: Address: esp321.local:6053
[14:45:18][C][api:139]: Using noise encryption: NO
[14:45:19][D][gps:040]: Location:
[14:45:19][D][gps:041]: Lat: 38.436832
[14:45:19][D][gps:042]: Lon: 45.778122
[14:45:19][D][gps:047]: Speed:
[14:45:19][D][gps:048]: 0.500040 km/h
[14:45:19][D][gps:052]: Course:
[14:45:19][D][gps:053]: 0.000000 °
[14:45:19][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:19][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:19’
[14:45:19][D][sensor:113]: ‘Current time stamp’: Sending state 1635938.00000 with 1 decimals of accuracy
[14:45:19][D][gps:040]: Location:
[14:45:19][D][gps:041]: Lat: 38.436832
[14:45:19][D][gps:042]: Lon: 45.778122
[14:45:19][D][gps:057]: Altitude:
[14:45:19][D][gps:058]: 1336.500000 m
[14:45:19][D][gps:062]: Satellites:
[14:45:19][D][gps:063]: 7
[14:45:19][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:20][D][gps:040]: Location:
[14:45:20][D][gps:041]: Lat: 38.436832
[14:45:20][D][gps:042]: Lon: 45.778122
[14:45:20][D][gps:047]: Speed:
[14:45:20][D][gps:048]: 0.277800 km/h
[14:45:20][D][gps:052]: Course:
[14:45:20][D][gps:053]: 0.000000 °
[14:45:20][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:20][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:20’
[14:45:20][D][sensor:113]: ‘Current time stamp’: Sending state 1635938.00000 with 1 decimals of accuracy
[14:45:20][D][gps:040]: Location:
[14:45:20][D][gps:041]: Lat: 38.436832
[14:45:20][D][gps:042]: Lon: 45.778122
[14:45:20][D][gps:057]: Altitude:
[14:45:20][D][gps:058]: 1336.699951 m
[14:45:20][D][gps:062]: Satellites:
[14:45:20][D][gps:063]: 7
[14:45:20][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:21][D][gps:040]: Location:
[14:45:21][D][gps:041]: Lat: 38.436832
[14:45:21][D][gps:042]: Lon: 45.778122
[14:45:21][D][gps:047]: Speed:
[14:45:21][D][gps:048]: 0.092600 km/h
[14:45:21][D][gps:052]: Course:
[14:45:21][D][gps:053]: 0.000000 °
[14:45:21][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:21][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:21’
[14:45:21][D][gps:040]: Location:
[14:45:21][D][gps:041]: Lat: 38.436832
[14:45:21][D][gps:042]: Lon: 45.778122
[14:45:21][D][gps:057]: Altitude:
[14:45:21][D][gps:058]: 1336.800049 m
[14:45:21][D][gps:062]: Satellites:
[14:45:21][D][gps:063]: 7
[14:45:21][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:22][D][gps:040]: Location:
[14:45:22][D][gps:041]: Lat: 38.436832
[14:45:22][D][gps:042]: Lon: 45.778118
[14:45:22][D][gps:047]: Speed:
[14:45:22][D][gps:048]: 0.574120 km/h
[14:45:22][D][gps:052]: Course:
[14:45:22][D][gps:053]: 0.000000 °
[14:45:22][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:22][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:22’
[14:45:22][D][sensor:113]: ‘Current time stamp’: Sending state 1635938.00000 with 1 decimals of accuracy
[14:45:22][D][gps:040]: Location:
[14:45:22][D][gps:041]: Lat: 38.436832
[14:45:22][D][gps:042]: Lon: 45.778118
[14:45:22][D][gps:057]: Altitude:
[14:45:22][D][gps:058]: 1337.300049 m
[14:45:22][D][gps:062]: Satellites:
[14:45:22][D][gps:063]: 7
[14:45:22][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:23][D][gps:040]: Location:
[14:45:23][D][gps:041]: Lat: 38.436832
[14:45:23][D][gps:042]: Lon: 45.778118
[14:45:23][D][gps:047]: Speed:
[14:45:23][D][gps:048]: 0.166680 km/h
[14:45:23][D][gps:052]: Course:
[14:45:23][D][gps:053]: 0.000000 °
[14:45:23][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:23][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:23’
[14:45:23][D][sensor:113]: ‘Current time stamp’: Sending state 1635938.00000 with 1 decimals of accuracy
[14:45:23][D][gps:040]: Location:
[14:45:23][D][gps:041]: Lat: 38.436832
[14:45:23][D][gps:042]: Lon: 45.778118
[14:45:23][D][gps:057]: Altitude:
[14:45:23][D][gps:058]: 1337.400024 m
[14:45:23][D][gps:062]: Satellites:
[14:45:23][D][gps:063]: 7
[14:45:23][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:24][D][gps:040]: Location:
[14:45:24][D][gps:041]: Lat: 38.436832
[14:45:24][D][gps:042]: Lon: 45.778118
[14:45:24][D][gps:047]: Speed:
[14:45:24][D][gps:048]: 0.777840 km/h
[14:45:24][D][gps:052]: Course:
[14:45:24][D][gps:053]: 0.000000 °
[14:45:24][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:24][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:24’
[14:45:25][D][gps:040]: Location:
[14:45:25][D][gps:041]: Lat: 38.436832
[14:45:25][D][gps:042]: Lon: 45.778118
[14:45:25][D][gps:047]: Speed:
[14:45:25][D][gps:048]: 0.777840 km/h
[14:45:25][D][gps:052]: Course:
[14:45:25][D][gps:053]: 0.000000 °
[14:45:25][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:25][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:25’
[14:45:25][D][sensor:113]: ‘Current time stamp’: Sending state 1635938.00000 with 1 decimals of accuracy
[14:45:25][D][gps:040]: Location:
[14:45:25][D][gps:041]: Lat: 38.436832
[14:45:25][D][gps:042]: Lon: 45.778118
[14:45:25][D][gps:057]: Altitude:
[14:45:25][D][gps:058]: 1337.599976 m
[14:45:25][D][gps:062]: Satellites:
[14:45:25][D][gps:063]: 7
[14:45:25][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:26][D][gps:040]: Location:
[14:45:26][D][gps:041]: Lat: 38.436832
[14:45:26][D][gps:042]: Lon: 45.778118
[14:45:26][D][gps:047]: Speed:
[14:45:26][D][gps:048]: 0.259280 km/h
[14:45:26][D][gps:052]: Course:
[14:45:26][D][gps:053]: 0.000000 °
[14:45:26][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:26][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:26’
[14:45:26][D][sensor:113]: ‘Current time stamp’: Sending state 1635938.00000 with 1 decimals of accuracy
[14:45:26][D][gps:040]: Location:
[14:45:26][D][gps:041]: Lat: 38.436832
[14:45:26][D][gps:042]: Lon: 45.778118
[14:45:26][D][gps:057]: Altitude:
[14:45:26][D][gps:058]: 1337.699951 m
[14:45:26][D][gps:062]: Satellites:
[14:45:26][D][gps:063]: 7
[14:45:26][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:27][D][gps:040]: Location:
[14:45:27][D][gps:041]: Lat: 38.436832
[14:45:27][D][gps:042]: Lon: 45.778118
[14:45:27][D][gps:047]: Speed:
[14:45:27][D][gps:048]: 0.018520 km/h
[14:45:27][D][gps:052]: Course:
[14:45:27][D][gps:053]: 0.000000 °
[14:45:27][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy
[14:45:27][D][text_sensor:067]: ‘Template Text Sensor’: Sending state ‘2021-11-03 14:45:27’
[14:45:27][D][sensor:113]: ‘Current time stamp’: Sending state 1635938.00000 with 1 decimals of accuracy
[14:45:27][D][gps:040]: Location:
[14:45:27][D][gps:041]: Lat: 38.436832
[14:45:27][D][gps:042]: Lon: 45.778118
[14:45:27][D][gps:057]: Altitude:
[14:45:27][D][gps:058]: 1337.800049 m
[14:45:27][D][gps:062]: Satellites:
[14:45:27][D][gps:063]: 7
[14:45:27][D][sensor:113]: ‘Template Sensor’: Sending state 1635938176.00000 with 0 decimals of accuracy

I tried a few things to fix this.

 if (id(gps_time).utcnow().is_valid()) {
            id(timestamp_sec).publish_state(id(gps_time).utcnow().timestamp / 1000 );

to

 if (id(gps_time).utcnow().is_valid()) {
            id(timestamp_sec).publish_state(id(gps_time).utcnow().timestamp  );

but timestamp not updated every second.
timestamp updating every 120 seconds.

This is where the discussion started. The state is a float and cannot hold milliseconds back to 1970 with 1 second precision.

You have to publish the timestamp in seconds to HA, not in milliseconds. To do so you have to kept the divider /1000 in the calculation. Why did you remove it?

before removed it ; entity state :1970-01-19T22:25:41+00:00
after remove it ; entity state : 2021-11-03T12:20:16+00:00

Sorry, my English is not good.

I stand corrected.
The HA timestamp sensor really expects the time in milliseconds. I was wrong about that.

I did some real testing now and there seems to be now way to get around the fact that some precision is lost when you write a timestamp. You lose ±64 seconds of precision.

An option would be to write the timestamp into a text_sensor. But there is no device_class for text_sensors and HA will not interpret this sensor as a time. It is simply a string.

May I ask why you need that timestamp? HA stores each sensor update together with the time anyway.

Thank you very much for your help.
I need to build a traccar client with osmand protocol. Traccar Client use this protocol to report GPS data to the server side.
http://demo.traccar.org:5055/?id=123456&lat={0}&lon={1}&timestamp={2}&hdop={3}&altitude={4}&speed={5}

"You lose ±64 seconds of precision "Isn’t this a issues?

It definitely is.
I added to your issue report with two proposals how to solve that.
Unfortunately both are feature requests. I hope that Otto will read and will give some feedback. I don’t want to flood the tracker with useless feature requests.

1 Like