ESPHome 2026.2.4
Loading...
Searching...
No Matches
uptime_text_sensor.cpp
Go to the documentation of this file.
2
3#include "esphome/core/hal.h"
5#include "esphome/core/log.h"
6
7namespace esphome {
8namespace uptime {
9
10static const char *const TAG = "uptime.sensor";
11
12static void append_unit(char *buf, size_t buf_size, size_t &pos, const char *separator, unsigned value,
13 const char *label) {
14 if (pos > 0) {
15 pos = buf_append_printf(buf, buf_size, pos, "%s", separator);
16 }
17 pos = buf_append_printf(buf, buf_size, pos, "%u%s", value, label);
18}
19
21 this->last_ms_ = millis();
22 if (this->last_ms_ < 60 * 1000)
23 this->last_ms_ = 0;
24 this->update();
25}
26
28 auto now = millis();
29 // get whole seconds since last update. Note that even if the millis count has overflowed between updates,
30 // the difference will still be correct due to the way twos-complement arithmetic works.
31 uint32_t delta = now - this->last_ms_;
32 this->last_ms_ = now - delta % 1000; // save remainder for next update
33 delta /= 1000;
34 this->uptime_ += delta;
35 uint32_t uptime = this->uptime_;
36 unsigned interval = this->get_update_interval() / 1000;
37
38 // Calculate all time units
39 unsigned seconds = uptime % 60;
40 uptime /= 60;
41 unsigned minutes = uptime % 60;
42 uptime /= 60;
43 unsigned hours = uptime % 24;
44 uptime /= 24;
45 unsigned days = uptime;
46
47 // Determine which units to display based on interval thresholds
48 bool seconds_enabled = interval < 30;
49 bool minutes_enabled = interval < 1800;
50 bool hours_enabled = interval < 12 * 3600;
51
52 // Show from highest non-zero unit (or all in expand mode) down to smallest enabled
53 bool show_days = this->expand_ || days > 0;
54 bool show_hours = hours_enabled && (show_days || hours > 0);
55 bool show_minutes = minutes_enabled && (show_hours || minutes > 0);
56 bool show_seconds = seconds_enabled && (show_minutes || seconds > 0);
57
58 // If nothing shown, show smallest enabled unit
59 if (!show_days && !show_hours && !show_minutes && !show_seconds) {
60 if (seconds_enabled) {
61 show_seconds = true;
62 } else if (minutes_enabled) {
63 show_minutes = true;
64 } else if (hours_enabled) {
65 show_hours = true;
66 } else {
67 show_days = true;
68 }
69 }
70
71 // Build output string on stack
72 // Home Assistant max state length is 255 chars + null terminator
73 char buf[256];
74 size_t pos = 0;
75 buf[0] = '\0'; // Initialize for empty case
76
77 if (show_days)
78 append_unit(buf, sizeof(buf), pos, this->separator_, days, this->days_text_);
79 if (show_hours)
80 append_unit(buf, sizeof(buf), pos, this->separator_, hours, this->hours_text_);
81 if (show_minutes)
82 append_unit(buf, sizeof(buf), pos, this->separator_, minutes, this->minutes_text_);
83 if (show_seconds)
84 append_unit(buf, sizeof(buf), pos, this->separator_, seconds, this->seconds_text_);
85
86 this->publish_state(buf);
87}
88
90void UptimeTextSensor::dump_config() { LOG_TEXT_SENSOR("", "Uptime Text Sensor", this); }
91
92} // namespace uptime
93} // namespace esphome
virtual uint32_t get_update_interval() const
Get the update interval in ms of this sensor.
void publish_state(const std::string &state)
float get_setup_priority() const override
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition component.cpp:83
const char *const TAG
Definition spi.cpp:7
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
size_t size_t pos
Definition helpers.h:729
uint32_t IRAM_ATTR HOT millis()
Definition core.cpp:25