1
0
mirror of https://github.com/esphome/esphome.git synced 2025-01-18 12:05:41 +00:00

[uptime] Add text_sensor (#8028)

This commit is contained in:
Clyde Stubbs 2025-01-15 09:27:47 +11:00 committed by GitHub
parent bdb1094b47
commit fc2b15e307
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 97 additions and 3 deletions

View File

@ -1,14 +1,14 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import sensor, time
import esphome.config_validation as cv
from esphome.const import (
CONF_TIME_ID,
DEVICE_CLASS_DURATION,
DEVICE_CLASS_TIMESTAMP,
ENTITY_CATEGORY_DIAGNOSTIC,
ICON_TIMER,
STATE_CLASS_TOTAL_INCREASING,
UNIT_SECOND,
ICON_TIMER,
DEVICE_CLASS_DURATION,
)
uptime_ns = cg.esphome_ns.namespace("uptime")

View File

@ -0,0 +1,19 @@
import esphome.codegen as cg
from esphome.components import text_sensor
import esphome.config_validation as cv
from esphome.const import ENTITY_CATEGORY_DIAGNOSTIC, ICON_TIMER
uptime_ns = cg.esphome_ns.namespace("uptime")
UptimeTextSensor = uptime_ns.class_(
"UptimeTextSensor", text_sensor.TextSensor, cg.PollingComponent
)
CONFIG_SCHEMA = text_sensor.text_sensor_schema(
UptimeTextSensor,
icon=ICON_TIMER,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
).extend(cv.polling_component_schema("60s"))
async def to_code(config):
var = await text_sensor.new_text_sensor(config)
await cg.register_component(var, config)

View File

@ -0,0 +1,46 @@
#include "uptime_text_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 UptimeTextSensor::setup() { this->last_ms_ = millis(); }
void UptimeTextSensor::update() {
const 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.
const uint32_t delta = (now - this->last_ms_) / 1000;
if (delta == 0)
return;
// set last_ms_ to the last second boundary
this->last_ms_ = now - (now % 1000);
this->uptime_ += delta;
auto uptime = this->uptime_;
unsigned days = uptime / (24 * 3600);
unsigned seconds = uptime % (24 * 3600);
unsigned hours = seconds / 3600;
seconds %= 3600;
unsigned minutes = seconds / 60;
seconds %= 60;
if (days != 0) {
this->publish_state(str_sprintf("%dd%dh%dm%ds", days, hours, minutes, seconds));
} else if (hours != 0) {
this->publish_state(str_sprintf("%dh%dm%ds", hours, minutes, seconds));
} else if (minutes != 0) {
this->publish_state(str_sprintf("%dm%ds", minutes, seconds));
} else {
this->publish_state(str_sprintf("%ds", seconds));
}
}
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

View File

@ -0,0 +1,25 @@
#pragma once
#include "esphome/core/defines.h"
#include "esphome/components/text_sensor/text_sensor.h"
#include "esphome/core/component.h"
namespace esphome {
namespace uptime {
class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent {
public:
void update() override;
void dump_config() override;
void setup() override;
float get_setup_priority() const override;
protected:
uint64_t uptime_{0};
uint64_t last_ms_{0};
};
} // namespace uptime
} // namespace esphome

View File

@ -13,3 +13,7 @@ sensor:
- platform: uptime
name: Uptime Sensor Timestamp
type: timestamp
text_sensor:
- platform: uptime
name: Uptime Text