############################################################################################ # SPECIFIC DEVICE VARIABLE SUBSTITUTIONS # If NOT using a secrets file, just replace # these with the values (in quotes) ########################################################################################### substitutions: timezone: "Pacific/Auckland" sntp_update_interval: 6h # Set the duration between the sntp service polling # Network time servers https://www.ntppool.org/zone/@ sntp_server_1: !secret ntp_server_1 sntp_server_2: !secret ntp_server_2 sntp_server_3: !secret ntp_server_3 ########################################################################################### # Real time clock time source for ESPHome # If it's invalid, we fall back to an internal clock # https://esphome.io/components/time/index.html # https://esphome.io/components/time/sntp ########################################################################################### time: - platform: sntp id: sntp_time # Define the timezone of the device timezone: "${timezone}" # Change sync interval from default 5min to 6 hours (or as set in substitutions) update_interval: ${sntp_update_interval} # Set specific sntp servers to use servers: - "${sntp_server_1}" - "${sntp_server_2}" - "${sntp_server_3}" # Publish the time the device was last restarted on_time_sync: then: - logger.log: "Synchronised SNTP clock" - text_sensor.template.publish: id: time_sync state: "SNTP clock Syncd" # Update last restart time, but only once. - if: condition: lambda: 'return id(device_last_restart).state == "";' then: - text_sensor.template.publish: id: device_last_restart #state: !lambda 'return id(sntp_time).now().strftime("%a %d %b %Y - %I:%M:%S %p");' state: !lambda |- // grab the current SNTP time auto now = id(sntp_time).now(); // format it as e.g. "Fri 23 May 2025 - 03:45:12 PM" return now.strftime("%a %d %b %Y - %I:%M:%S %p"); text_sensor: # Creates a sensor showing when the device was last restarted - platform: template name: "Time: Last Restart" id: device_last_restart icon: mdi:clock entity_category: diagnostic #device_class: timestamp - platform: template name: "Time: Internal Time" id: time_text update_interval: "1min" entity_category: diagnostic lambda: |- // If SNTP time is valid, show real time/date. if (id(sntp_time).now().is_valid()) { auto t = id(sntp_time).now().strftime("%H:%M:%S - %d-%m-%Y"); return { t }; } // Fallback: show internal clock based on current_mins (minutes from midnight). // NOTE: current_mins is expected to be a global defined in the main device YAML. int mins = id(current_mins); if (mins < 0) mins = 0; if (mins >= 1440) mins = mins % 1440; int hour = mins / 60; int minute = mins % 60; char buff[32]; snprintf(buff, sizeof(buff), "%02d:%02d (fallback)", hour, minute); return { std::string(buff) }; - platform: template name: "Time: Sync Status" id: time_sync update_interval: "1min" entity_category: diagnostic