mirror of
https://github.com/esphome/esphome.git
synced 2025-07-27 21:56:34 +00:00
[uptime] Add format config for text_sensor (#8304)
This commit is contained in:
parent
248dbd32a5
commit
55e099450c
@ -1,19 +1,59 @@
|
|||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import text_sensor
|
from esphome.components import text_sensor
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import ENTITY_CATEGORY_DIAGNOSTIC, ICON_TIMER
|
from esphome.const import (
|
||||||
|
CONF_FORMAT,
|
||||||
|
CONF_HOURS,
|
||||||
|
CONF_ID,
|
||||||
|
CONF_MINUTES,
|
||||||
|
CONF_SECONDS,
|
||||||
|
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
ICON_TIMER,
|
||||||
|
)
|
||||||
|
|
||||||
uptime_ns = cg.esphome_ns.namespace("uptime")
|
uptime_ns = cg.esphome_ns.namespace("uptime")
|
||||||
UptimeTextSensor = uptime_ns.class_(
|
UptimeTextSensor = uptime_ns.class_(
|
||||||
"UptimeTextSensor", text_sensor.TextSensor, cg.PollingComponent
|
"UptimeTextSensor", text_sensor.TextSensor, cg.PollingComponent
|
||||||
)
|
)
|
||||||
CONFIG_SCHEMA = text_sensor.text_sensor_schema(
|
|
||||||
UptimeTextSensor,
|
CONF_SEPARATOR = "separator"
|
||||||
icon=ICON_TIMER,
|
CONF_DAYS = "days"
|
||||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
CONF_EXPAND = "expand"
|
||||||
).extend(cv.polling_component_schema("30s"))
|
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
text_sensor.text_sensor_schema(
|
||||||
|
UptimeTextSensor,
|
||||||
|
icon=ICON_TIMER,
|
||||||
|
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
)
|
||||||
|
.extend(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_FORMAT, default={}): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_DAYS, default="d"): cv.string_strict,
|
||||||
|
cv.Optional(CONF_HOURS, default="h"): cv.string_strict,
|
||||||
|
cv.Optional(CONF_MINUTES, default="m"): cv.string_strict,
|
||||||
|
cv.Optional(CONF_SECONDS, default="s"): cv.string_strict,
|
||||||
|
cv.Optional(CONF_SEPARATOR, default=""): cv.string_strict,
|
||||||
|
cv.Optional(CONF_EXPAND, default=False): cv.boolean,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.extend(cv.polling_component_schema("30s"))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
var = await text_sensor.new_text_sensor(config)
|
format = config[CONF_FORMAT]
|
||||||
|
var = cg.new_Pvariable(
|
||||||
|
config[CONF_ID],
|
||||||
|
format[CONF_DAYS],
|
||||||
|
format[CONF_HOURS],
|
||||||
|
format[CONF_MINUTES],
|
||||||
|
format[CONF_SECONDS],
|
||||||
|
format[CONF_SEPARATOR],
|
||||||
|
format[CONF_EXPAND],
|
||||||
|
)
|
||||||
|
await text_sensor.register_text_sensor(var, config)
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
|
@ -16,6 +16,11 @@ void UptimeTextSensor::setup() {
|
|||||||
this->update();
|
this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UptimeTextSensor::insert_buffer_(std::string &buffer, const char *key, unsigned value) const {
|
||||||
|
buffer.insert(0, this->separator_);
|
||||||
|
buffer.insert(0, str_sprintf("%u%s", value, key));
|
||||||
|
}
|
||||||
|
|
||||||
void UptimeTextSensor::update() {
|
void UptimeTextSensor::update() {
|
||||||
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,
|
||||||
@ -32,25 +37,25 @@ void UptimeTextSensor::update() {
|
|||||||
unsigned remainder = uptime % 60;
|
unsigned remainder = uptime % 60;
|
||||||
uptime /= 60;
|
uptime /= 60;
|
||||||
if (interval < 30) {
|
if (interval < 30) {
|
||||||
buffer.insert(0, str_sprintf("%us", remainder));
|
this->insert_buffer_(buffer, this->seconds_text_, remainder);
|
||||||
if (uptime == 0)
|
if (!this->expand_ && uptime == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
remainder = uptime % 60;
|
remainder = uptime % 60;
|
||||||
uptime /= 60;
|
uptime /= 60;
|
||||||
if (interval < 1800) {
|
if (interval < 1800) {
|
||||||
buffer.insert(0, str_sprintf("%um", remainder));
|
this->insert_buffer_(buffer, this->minutes_text_, remainder);
|
||||||
if (uptime == 0)
|
if (!this->expand_ && uptime == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
remainder = uptime % 24;
|
remainder = uptime % 24;
|
||||||
uptime /= 24;
|
uptime /= 24;
|
||||||
if (interval < 12 * 3600) {
|
if (interval < 12 * 3600) {
|
||||||
buffer.insert(0, str_sprintf("%uh", remainder));
|
this->insert_buffer_(buffer, this->hours_text_, remainder);
|
||||||
if (uptime == 0)
|
if (!this->expand_ && uptime == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer.insert(0, str_sprintf("%ud", (unsigned) uptime));
|
this->insert_buffer_(buffer, this->days_text_, (unsigned) uptime);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this->publish_state(buffer);
|
this->publish_state(buffer);
|
||||||
|
@ -10,13 +10,32 @@ namespace uptime {
|
|||||||
|
|
||||||
class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent {
|
class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent {
|
||||||
public:
|
public:
|
||||||
|
UptimeTextSensor(const char *days_text, const char *hours_text, const char *minutes_text, const char *seconds_text,
|
||||||
|
const char *separator, bool expand)
|
||||||
|
: days_text_(days_text),
|
||||||
|
hours_text_(hours_text),
|
||||||
|
minutes_text_(minutes_text),
|
||||||
|
seconds_text_(seconds_text),
|
||||||
|
separator_(separator),
|
||||||
|
expand_(expand) {}
|
||||||
void update() override;
|
void update() override;
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
void setup() override;
|
void setup() override;
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
void set_days(const char *days_text) { this->days_text_ = days_text; }
|
||||||
|
void set_hours(const char *hours_text) { this->hours_text_ = hours_text; }
|
||||||
|
void set_minutes(const char *minutes_text) { this->minutes_text_ = minutes_text; }
|
||||||
|
void set_seconds(const char *seconds_text) { this->seconds_text_ = seconds_text; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void insert_buffer_(std::string &buffer, const char *key, unsigned value) const;
|
||||||
|
const char *days_text_;
|
||||||
|
const char *hours_text_;
|
||||||
|
const char *minutes_text_;
|
||||||
|
const char *seconds_text_;
|
||||||
|
const char *separator_;
|
||||||
|
bool expand_{};
|
||||||
uint32_t uptime_{0}; // uptime in seconds, will overflow after 136 years
|
uint32_t uptime_{0}; // uptime in seconds, will overflow after 136 years
|
||||||
uint32_t last_ms_{0};
|
uint32_t last_ms_{0};
|
||||||
};
|
};
|
||||||
|
@ -17,3 +17,13 @@ sensor:
|
|||||||
text_sensor:
|
text_sensor:
|
||||||
- platform: uptime
|
- platform: uptime
|
||||||
name: Uptime Text
|
name: Uptime Text
|
||||||
|
- platform: uptime
|
||||||
|
name: Uptime Text With Separator
|
||||||
|
format:
|
||||||
|
separator: "-"
|
||||||
|
expand: true
|
||||||
|
days: "Days"
|
||||||
|
hours: "H"
|
||||||
|
minutes: "M"
|
||||||
|
seconds: "S"
|
||||||
|
update_interval: 10s
|
||||||
|
Loading…
x
Reference in New Issue
Block a user