mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 09:01:49 +00:00 
			
		
		
		
	[uptime] Cosmetic improvements for uptime text_sensor (#8101)
This commit is contained in:
		@@ -11,7 +11,7 @@ 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("60s"))
 | 
					).extend(cv.polling_component_schema("30s"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def to_code(config):
 | 
					async def to_code(config):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,34 +9,51 @@ namespace uptime {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static const char *const TAG = "uptime.sensor";
 | 
					static const char *const TAG = "uptime.sensor";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void UptimeTextSensor::setup() { this->last_ms_ = millis(); }
 | 
					void UptimeTextSensor::setup() {
 | 
				
			||||||
 | 
					  this->last_ms_ = millis();
 | 
				
			||||||
 | 
					  if (this->last_ms_ < 60 * 1000)
 | 
				
			||||||
 | 
					    this->last_ms_ = 0;
 | 
				
			||||||
 | 
					  this->update();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void UptimeTextSensor::update() {
 | 
					void UptimeTextSensor::update() {
 | 
				
			||||||
  const 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,
 | 
				
			||||||
  // the difference will still be correct due to the way twos-complement arithmetic works.
 | 
					  // the difference will still be correct due to the way twos-complement arithmetic works.
 | 
				
			||||||
  const uint32_t delta = (now - this->last_ms_) / 1000;
 | 
					  uint32_t delta = now - this->last_ms_;
 | 
				
			||||||
  if (delta == 0)
 | 
					  this->last_ms_ = now - delta % 1000;  // save remainder for next update
 | 
				
			||||||
    return;
 | 
					  delta /= 1000;
 | 
				
			||||||
  // set last_ms_ to the last second boundary
 | 
					 | 
				
			||||||
  this->last_ms_ = now - (now % 1000);
 | 
					 | 
				
			||||||
  this->uptime_ += delta;
 | 
					  this->uptime_ += delta;
 | 
				
			||||||
  auto uptime = this->uptime_;
 | 
					  auto uptime = this->uptime_;
 | 
				
			||||||
  unsigned days = uptime / (24 * 3600);
 | 
					  unsigned interval = this->get_update_interval() / 1000;
 | 
				
			||||||
  unsigned seconds = uptime % (24 * 3600);
 | 
					  std::string buffer{};
 | 
				
			||||||
  unsigned hours = seconds / 3600;
 | 
					  // display from the largest unit that corresponds to the update interval, drop larger units that are zero.
 | 
				
			||||||
  seconds %= 3600;
 | 
					  while (true) {  // enable use of break for early exit
 | 
				
			||||||
  unsigned minutes = seconds / 60;
 | 
					    unsigned remainder = uptime % 60;
 | 
				
			||||||
  seconds %= 60;
 | 
					    uptime /= 60;
 | 
				
			||||||
  if (days != 0) {
 | 
					    if (interval < 30) {
 | 
				
			||||||
    this->publish_state(str_sprintf("%dd%dh%dm%ds", days, hours, minutes, seconds));
 | 
					      buffer.insert(0, str_sprintf("%us", remainder));
 | 
				
			||||||
  } else if (hours != 0) {
 | 
					      if (uptime == 0)
 | 
				
			||||||
    this->publish_state(str_sprintf("%dh%dm%ds", hours, minutes, seconds));
 | 
					        break;
 | 
				
			||||||
  } else if (minutes != 0) {
 | 
					 | 
				
			||||||
    this->publish_state(str_sprintf("%dm%ds", minutes, seconds));
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    this->publish_state(str_sprintf("%ds", seconds));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    remainder = uptime % 60;
 | 
				
			||||||
 | 
					    uptime /= 60;
 | 
				
			||||||
 | 
					    if (interval < 1800) {
 | 
				
			||||||
 | 
					      buffer.insert(0, str_sprintf("%um", remainder));
 | 
				
			||||||
 | 
					      if (uptime == 0)
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    remainder = uptime % 24;
 | 
				
			||||||
 | 
					    uptime /= 24;
 | 
				
			||||||
 | 
					    if (interval < 12 * 3600) {
 | 
				
			||||||
 | 
					      buffer.insert(0, str_sprintf("%uh", remainder));
 | 
				
			||||||
 | 
					      if (uptime == 0)
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    buffer.insert(0, str_sprintf("%ud", (unsigned) uptime));
 | 
				
			||||||
 | 
					    break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  this->publish_state(buffer);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float UptimeTextSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
 | 
					float UptimeTextSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,8 +17,8 @@ class UptimeTextSensor : public text_sensor::TextSensor, public PollingComponent
 | 
				
			|||||||
  float get_setup_priority() const override;
 | 
					  float get_setup_priority() const override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 protected:
 | 
					 protected:
 | 
				
			||||||
  uint64_t uptime_{0};
 | 
					  uint32_t uptime_{0};  // uptime in seconds, will overflow after 136 years
 | 
				
			||||||
  uint64_t last_ms_{0};
 | 
					  uint32_t last_ms_{0};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace uptime
 | 
					}  // namespace uptime
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user