1
0
mirror of https://github.com/esphome/esphome.git synced 2025-01-31 10:10:56 +00:00

[uptime] Cosmetic improvements for uptime text_sensor (#8101)

This commit is contained in:
Clyde Stubbs 2025-01-21 13:43:50 +11:00 committed by GitHub
parent 576dbd6f0c
commit 0f4e274e52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 24 deletions

View File

@ -11,7 +11,7 @@ CONFIG_SCHEMA = text_sensor.text_sensor_schema(
UptimeTextSensor, UptimeTextSensor,
icon=ICON_TIMER, icon=ICON_TIMER,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC, entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
).extend(cv.polling_component_schema("60s")) ).extend(cv.polling_component_schema("30s"))
async def to_code(config): async def to_code(config):

View File

@ -9,34 +9,51 @@ namespace uptime {
static const char *const TAG = "uptime.sensor"; static const char *const TAG = "uptime.sensor";
void UptimeTextSensor::setup() { this->last_ms_ = millis(); } void UptimeTextSensor::setup() {
this->last_ms_ = millis();
if (this->last_ms_ < 60 * 1000)
this->last_ms_ = 0;
this->update();
}
void UptimeTextSensor::update() { void UptimeTextSensor::update() {
const auto now = millis(); auto now = millis();
// get whole seconds since last update. Note that even if the millis count has overflowed between updates, // get whole seconds since last update. Note that even if the millis count has overflowed between updates,
// the difference will still be correct due to the way twos-complement arithmetic works. // the difference will still be correct due to the way twos-complement arithmetic works.
const uint32_t delta = (now - this->last_ms_) / 1000; uint32_t delta = now - this->last_ms_;
if (delta == 0) this->last_ms_ = now - delta % 1000; // save remainder for next update
return; delta /= 1000;
// set last_ms_ to the last second boundary
this->last_ms_ = now - (now % 1000);
this->uptime_ += delta; this->uptime_ += delta;
auto uptime = this->uptime_; auto uptime = this->uptime_;
unsigned days = uptime / (24 * 3600); unsigned interval = this->get_update_interval() / 1000;
unsigned seconds = uptime % (24 * 3600); std::string buffer{};
unsigned hours = seconds / 3600; // display from the largest unit that corresponds to the update interval, drop larger units that are zero.
seconds %= 3600; while (true) { // enable use of break for early exit
unsigned minutes = seconds / 60; unsigned remainder = uptime % 60;
seconds %= 60; uptime /= 60;
if (days != 0) { if (interval < 30) {
this->publish_state(str_sprintf("%dd%dh%dm%ds", days, hours, minutes, seconds)); buffer.insert(0, str_sprintf("%us", remainder));
} else if (hours != 0) { if (uptime == 0)
this->publish_state(str_sprintf("%dh%dm%ds", hours, minutes, seconds)); break;
} else if (minutes != 0) { }
this->publish_state(str_sprintf("%dm%ds", minutes, seconds)); remainder = uptime % 60;
} else { uptime /= 60;
this->publish_state(str_sprintf("%ds", seconds)); if (interval < 1800) {
buffer.insert(0, str_sprintf("%um", remainder));
if (uptime == 0)
break;
}
remainder = uptime % 24;
uptime /= 24;
if (interval < 12 * 3600) {
buffer.insert(0, str_sprintf("%uh", remainder));
if (uptime == 0)
break;
}
buffer.insert(0, str_sprintf("%ud", (unsigned) uptime));
break;
} }
this->publish_state(buffer);
} }
float UptimeTextSensor::get_setup_priority() const { return setup_priority::HARDWARE; } float UptimeTextSensor::get_setup_priority() const { return setup_priority::HARDWARE; }

View File

@ -17,8 +17,8 @@ class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent
float get_setup_priority() const override; float get_setup_priority() const override;
protected: protected:
uint64_t uptime_{0}; uint32_t uptime_{0}; // uptime in seconds, will overflow after 136 years
uint64_t last_ms_{0}; uint32_t last_ms_{0};
}; };
} // namespace uptime } // namespace uptime