Merge remote-tracking branch 'upstream/uptime_use_millis_64' into integration

This commit is contained in:
J. Nick Koston
2026-02-20 20:22:35 -06:00
6 changed files with 19 additions and 61 deletions
@@ -1,30 +1,16 @@
#include "uptime_seconds_sensor.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include "esphome/core/application.h"
#include "esphome/core/log.h"
namespace esphome {
namespace uptime {
namespace esphome::uptime {
static const char *const TAG = "uptime.sensor";
void UptimeSecondsSensor::update() {
const uint32_t ms = millis();
const uint64_t ms_mask = (1ULL << 32) - 1ULL;
const uint32_t last_ms = this->uptime_ & ms_mask;
if (ms < last_ms) {
this->uptime_ += ms_mask + 1ULL;
ESP_LOGD(TAG, "Detected roll-over \xf0\x9f\xa6\x84");
}
this->uptime_ &= ~ms_mask;
this->uptime_ |= ms;
// Do separate second and milliseconds conversion to avoid floating point division errors
// Probably some IEEE standard already guarantees this division can be done without loss
// of precision in a single division, but let's do it like this to be sure.
const uint64_t seconds_int = this->uptime_ / 1000ULL;
const float seconds = float(seconds_int) + (this->uptime_ % 1000ULL) / 1000.0f;
const uint64_t uptime = App.scheduler.millis_64();
const uint64_t seconds_int = uptime / 1000ULL;
const float seconds = float(seconds_int) + (uptime % 1000ULL) / 1000.0f;
this->publish_state(seconds);
}
float UptimeSecondsSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
@@ -33,5 +19,4 @@ void UptimeSecondsSensor::dump_config() {
ESP_LOGCONFIG(TAG, " Type: Seconds");
}
} // namespace uptime
} // namespace esphome
} // namespace esphome::uptime
@@ -3,8 +3,7 @@
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/component.h"
namespace esphome {
namespace uptime {
namespace esphome::uptime {
class UptimeSecondsSensor : public sensor::Sensor, public PollingComponent {
public:
@@ -12,10 +11,6 @@ class UptimeSecondsSensor : public sensor::Sensor, public PollingComponent {
void dump_config() override;
float get_setup_priority() const override;
protected:
uint64_t uptime_{0};
};
} // namespace uptime
} // namespace esphome
} // namespace esphome::uptime
@@ -6,8 +6,7 @@
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace uptime {
namespace esphome::uptime {
static const char *const TAG = "uptime.sensor";
@@ -33,7 +32,6 @@ void UptimeTimestampSensor::dump_config() {
ESP_LOGCONFIG(TAG, " Type: Timestamp");
}
} // namespace uptime
} // namespace esphome
} // namespace esphome::uptime
#endif // USE_TIME
@@ -8,8 +8,7 @@
#include "esphome/components/time/real_time_clock.h"
#include "esphome/core/component.h"
namespace esphome {
namespace uptime {
namespace esphome::uptime {
class UptimeTimestampSensor : public sensor::Sensor, public Component {
public:
@@ -24,7 +23,6 @@ class UptimeTimestampSensor : public sensor::Sensor, public Component {
time::RealTimeClock *time_;
};
} // namespace uptime
} // namespace esphome
} // namespace esphome::uptime
#endif // USE_TIME
@@ -1,11 +1,10 @@
#include "uptime_text_sensor.h"
#include "esphome/core/hal.h"
#include "esphome/core/application.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace uptime {
namespace esphome::uptime {
static const char *const TAG = "uptime.sensor";
@@ -17,22 +16,10 @@ static void append_unit(char *buf, size_t buf_size, size_t &pos, const char *sep
pos = buf_append_printf(buf, buf_size, pos, "%u%s", value, label);
}
void UptimeTextSensor::setup() {
this->last_ms_ = millis();
if (this->last_ms_ < 60 * 1000)
this->last_ms_ = 0;
this->update();
}
void UptimeTextSensor::setup() { this->update(); }
void UptimeTextSensor::update() {
auto now = millis();
// 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.
uint32_t delta = now - this->last_ms_;
this->last_ms_ = now - delta % 1000; // save remainder for next update
delta /= 1000;
this->uptime_ += delta;
uint32_t uptime = this->uptime_;
uint32_t uptime = static_cast<uint32_t>(App.scheduler.millis_64() / 1000);
unsigned interval = this->get_update_interval() / 1000;
// Calculate all time units
@@ -89,5 +76,4 @@ void UptimeTextSensor::update() {
float UptimeTextSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
void UptimeTextSensor::dump_config() { LOG_TEXT_SENSOR("", "Uptime Text Sensor", this); }
} // namespace uptime
} // namespace esphome
} // namespace esphome::uptime
@@ -5,8 +5,7 @@
#include "esphome/components/text_sensor/text_sensor.h"
#include "esphome/core/component.h"
namespace esphome {
namespace uptime {
namespace esphome::uptime {
class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent {
public:
@@ -35,9 +34,6 @@ class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent
const char *seconds_text_;
const char *separator_;
bool expand_{};
uint32_t uptime_{0}; // uptime in seconds, will overflow after 136 years
uint32_t last_ms_{0};
};
} // namespace uptime
} // namespace esphome
} // namespace esphome::uptime