[uptime] Add new timestamp type for uptime sensor (#7029)

* [uptime] Add new timestamp type for uptime sensor

* Remove debug logs
This commit is contained in:
Jesse Hills 2024-07-02 14:29:49 +12:00 committed by GitHub
parent 5e6c69b930
commit d8f0dce08f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 138 additions and 20 deletions

View File

@ -1,7 +1,9 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor
from esphome.components import sensor, time
from esphome.const import (
CONF_TIME_ID,
DEVICE_CLASS_TIMESTAMP,
ENTITY_CATEGORY_DIAGNOSTIC,
STATE_CLASS_TOTAL_INCREASING,
UNIT_SECOND,
@ -10,19 +12,50 @@ from esphome.const import (
)
uptime_ns = cg.esphome_ns.namespace("uptime")
UptimeSensor = uptime_ns.class_("UptimeSensor", sensor.Sensor, cg.PollingComponent)
UptimeSecondsSensor = uptime_ns.class_(
"UptimeSecondsSensor", sensor.Sensor, cg.PollingComponent
)
UptimeTimestampSensor = uptime_ns.class_(
"UptimeTimestampSensor", sensor.Sensor, cg.Component
)
CONFIG_SCHEMA = sensor.sensor_schema(
UptimeSensor,
CONFIG_SCHEMA = cv.typed_schema(
{
"seconds": sensor.sensor_schema(
UptimeSecondsSensor,
unit_of_measurement=UNIT_SECOND,
icon=ICON_TIMER,
accuracy_decimals=0,
state_class=STATE_CLASS_TOTAL_INCREASING,
device_class=DEVICE_CLASS_DURATION,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
).extend(cv.polling_component_schema("60s"))
).extend(cv.polling_component_schema("60s")),
"timestamp": sensor.sensor_schema(
UptimeTimestampSensor,
icon=ICON_TIMER,
accuracy_decimals=0,
device_class=DEVICE_CLASS_TIMESTAMP,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
)
.extend(
cv.Schema(
{
cv.GenerateID(CONF_TIME_ID): cv.All(
cv.requires_component("time"), cv.use_id(time.RealTimeClock)
),
}
)
)
.extend(cv.COMPONENT_SCHEMA),
},
default_type="seconds",
)
async def to_code(config):
var = await sensor.new_sensor(config)
await cg.register_component(var, config)
if time_id_config := config.get(CONF_TIME_ID):
time_id = await cg.get_variable(time_id_config)
cg.add(var.set_time(time_id))

View File

@ -1,14 +1,15 @@
#include "uptime_sensor.h"
#include "esphome/core/log.h"
#include "esphome/core/helpers.h"
#include "uptime_seconds_sensor.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace uptime {
static const char *const TAG = "uptime.sensor";
void UptimeSensor::update() {
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;
@ -26,9 +27,12 @@ void UptimeSensor::update() {
const float seconds = float(seconds_int) + (this->uptime_ % 1000ULL) / 1000.0f;
this->publish_state(seconds);
}
std::string UptimeSensor::unique_id() { return get_mac_address() + "-uptime"; }
float UptimeSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
void UptimeSensor::dump_config() { LOG_SENSOR("", "Uptime Sensor", this); }
std::string UptimeSecondsSensor::unique_id() { return get_mac_address() + "-uptime"; }
float UptimeSecondsSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
void UptimeSecondsSensor::dump_config() {
LOG_SENSOR("", "Uptime Sensor", this);
ESP_LOGCONFIG(TAG, " Type: Seconds");
}
} // namespace uptime
} // namespace esphome

View File

@ -1,12 +1,12 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/component.h"
namespace esphome {
namespace uptime {
class UptimeSensor : public sensor::Sensor, public PollingComponent {
class UptimeSecondsSensor : public sensor::Sensor, public PollingComponent {
public:
void update() override;
void dump_config() override;

View File

@ -0,0 +1,39 @@
#include "uptime_timestamp_sensor.h"
#ifdef USE_TIME
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome {
namespace uptime {
static const char *const TAG = "uptime.sensor";
void UptimeTimestampSensor::setup() {
this->time_->add_on_time_sync_callback([this]() {
if (this->has_state_)
return; // No need to update the timestamp if it's already set
auto now = this->time_->now();
const uint32_t ms = millis();
if (!now.is_valid())
return; // No need to update the timestamp if the time is not valid
time_t timestamp = now.timestamp;
uint32_t seconds = ms / 1000;
timestamp -= seconds;
this->publish_state(timestamp);
});
}
float UptimeTimestampSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
void UptimeTimestampSensor::dump_config() {
LOG_SENSOR("", "Uptime Sensor", this);
ESP_LOGCONFIG(TAG, " Type: Timestamp");
}
} // namespace uptime
} // namespace esphome
#endif // USE_TIME

View File

@ -0,0 +1,30 @@
#pragma once
#include "esphome/core/defines.h"
#ifdef USE_TIME
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/time/real_time_clock.h"
#include "esphome/core/component.h"
namespace esphome {
namespace uptime {
class UptimeTimestampSensor : public sensor::Sensor, public Component {
public:
void setup() override;
void dump_config() override;
float get_setup_priority() const override;
void set_time(time::RealTimeClock *time) { this->time_ = time; }
protected:
time::RealTimeClock *time_;
};
} // namespace uptime
} // namespace esphome
#endif // USE_TIME

View File

@ -1,3 +1,15 @@
wifi:
ap:
time:
- platform: sntp
sensor:
- platform: uptime
name: Uptime Sensor
- platform: uptime
name: Uptime Sensor Seconds
type: seconds
- platform: uptime
name: Uptime Sensor Timestamp
type: timestamp