mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[uptime] Add format config for text_sensor (#8304)
This commit is contained in:
		| @@ -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( |  | ||||||
|  | CONF_SEPARATOR = "separator" | ||||||
|  | CONF_DAYS = "days" | ||||||
|  | CONF_EXPAND = "expand" | ||||||
|  |  | ||||||
|  | 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("30s")) |     ) | ||||||
|  |     .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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user