mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 09:01:49 +00:00 
			
		
		
		
	RTC implementation of pcf8563 (#4998)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		@@ -201,6 +201,7 @@ esphome/components/output/* @esphome/core
 | 
				
			|||||||
esphome/components/pca6416a/* @Mat931
 | 
					esphome/components/pca6416a/* @Mat931
 | 
				
			||||||
esphome/components/pca9554/* @hwstar
 | 
					esphome/components/pca9554/* @hwstar
 | 
				
			||||||
esphome/components/pcf85063/* @brogon
 | 
					esphome/components/pcf85063/* @brogon
 | 
				
			||||||
 | 
					esphome/components/pcf8563/* @KoenBreeman
 | 
				
			||||||
esphome/components/pid/* @OttoWinter
 | 
					esphome/components/pid/* @OttoWinter
 | 
				
			||||||
esphome/components/pipsolar/* @andreashergert1984
 | 
					esphome/components/pipsolar/* @andreashergert1984
 | 
				
			||||||
esphome/components/pm1006/* @habbie
 | 
					esphome/components/pm1006/* @habbie
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										0
									
								
								esphome/components/pcf8563/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								esphome/components/pcf8563/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										109
									
								
								esphome/components/pcf8563/pcf8563.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								esphome/components/pcf8563/pcf8563.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					#include "pcf8563.h"
 | 
				
			||||||
 | 
					#include "esphome/core/log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Datasheet:
 | 
				
			||||||
 | 
					// - https://nl.mouser.com/datasheet/2/302/PCF8563-1127619.pdf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace esphome {
 | 
				
			||||||
 | 
					namespace pcf8563 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *const TAG = "PCF8563";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PCF8563Component::setup() {
 | 
				
			||||||
 | 
					  ESP_LOGCONFIG(TAG, "Setting up PCF8563...");
 | 
				
			||||||
 | 
					  if (!this->read_rtc_()) {
 | 
				
			||||||
 | 
					    this->mark_failed();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PCF8563Component::update() { this->read_time(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PCF8563Component::dump_config() {
 | 
				
			||||||
 | 
					  ESP_LOGCONFIG(TAG, "PCF8563:");
 | 
				
			||||||
 | 
					  LOG_I2C_DEVICE(this);
 | 
				
			||||||
 | 
					  if (this->is_failed()) {
 | 
				
			||||||
 | 
					    ESP_LOGE(TAG, "Communication with PCF8563 failed!");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ESP_LOGCONFIG(TAG, "  Timezone: '%s'", this->timezone_.c_str());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float PCF8563Component::get_setup_priority() const { return setup_priority::DATA; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PCF8563Component::read_time() {
 | 
				
			||||||
 | 
					  if (!this->read_rtc_()) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (pcf8563_.reg.stop) {
 | 
				
			||||||
 | 
					    ESP_LOGW(TAG, "RTC halted, not syncing to system clock.");
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ESPTime rtc_time{
 | 
				
			||||||
 | 
					      .second = uint8_t(pcf8563_.reg.second + 10 * pcf8563_.reg.second_10),
 | 
				
			||||||
 | 
					      .minute = uint8_t(pcf8563_.reg.minute + 10u * pcf8563_.reg.minute_10),
 | 
				
			||||||
 | 
					      .hour = uint8_t(pcf8563_.reg.hour + 10u * pcf8563_.reg.hour_10),
 | 
				
			||||||
 | 
					      .day_of_week = uint8_t(pcf8563_.reg.weekday),
 | 
				
			||||||
 | 
					      .day_of_month = uint8_t(pcf8563_.reg.day + 10u * pcf8563_.reg.day_10),
 | 
				
			||||||
 | 
					      .day_of_year = 1,  // ignored by recalc_timestamp_utc(false)
 | 
				
			||||||
 | 
					      .month = uint8_t(pcf8563_.reg.month + 10u * pcf8563_.reg.month_10),
 | 
				
			||||||
 | 
					      .year = uint16_t(pcf8563_.reg.year + 10u * pcf8563_.reg.year_10 + 2000),
 | 
				
			||||||
 | 
					      .is_dst = false,  // not used
 | 
				
			||||||
 | 
					      .timestamp = 0,   // overwritten by recalc_timestamp_utc(false)
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  rtc_time.recalc_timestamp_utc(false);
 | 
				
			||||||
 | 
					  if (!rtc_time.is_valid()) {
 | 
				
			||||||
 | 
					    ESP_LOGE(TAG, "Invalid RTC time, not syncing to system clock.");
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  time::RealTimeClock::synchronize_epoch_(rtc_time.timestamp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void PCF8563Component::write_time() {
 | 
				
			||||||
 | 
					  auto now = time::RealTimeClock::utcnow();
 | 
				
			||||||
 | 
					  if (!now.is_valid()) {
 | 
				
			||||||
 | 
					    ESP_LOGE(TAG, "Invalid system time, not syncing to RTC.");
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  pcf8563_.reg.year = (now.year - 2000) % 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.year_10 = (now.year - 2000) / 10 % 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.month = now.month % 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.month_10 = now.month / 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.day = now.day_of_month % 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.day_10 = now.day_of_month / 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.weekday = now.day_of_week;
 | 
				
			||||||
 | 
					  pcf8563_.reg.hour = now.hour % 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.hour_10 = now.hour / 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.minute = now.minute % 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.minute_10 = now.minute / 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.second = now.second % 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.second_10 = now.second / 10;
 | 
				
			||||||
 | 
					  pcf8563_.reg.stop = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  this->write_rtc_();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool PCF8563Component::read_rtc_() {
 | 
				
			||||||
 | 
					  if (!this->read_bytes(0, this->pcf8563_.raw, sizeof(this->pcf8563_.raw))) {
 | 
				
			||||||
 | 
					    ESP_LOGE(TAG, "Can't read I2C data.");
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ESP_LOGD(TAG, "Read  %0u%0u:%0u%0u:%0u%0u 20%0u%0u-%0u%0u-%0u%0u  STOP:%s CLKOUT:%0u", pcf8563_.reg.hour_10,
 | 
				
			||||||
 | 
					           pcf8563_.reg.hour, pcf8563_.reg.minute_10, pcf8563_.reg.minute, pcf8563_.reg.second_10, pcf8563_.reg.second,
 | 
				
			||||||
 | 
					           pcf8563_.reg.year_10, pcf8563_.reg.year, pcf8563_.reg.month_10, pcf8563_.reg.month, pcf8563_.reg.day_10,
 | 
				
			||||||
 | 
					           pcf8563_.reg.day, ONOFF(!pcf8563_.reg.stop), pcf8563_.reg.clkout_enabled);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool PCF8563Component::write_rtc_() {
 | 
				
			||||||
 | 
					  if (!this->write_bytes(0, this->pcf8563_.raw, sizeof(this->pcf8563_.raw))) {
 | 
				
			||||||
 | 
					    ESP_LOGE(TAG, "Can't write I2C data.");
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ESP_LOGD(TAG, "Write %0u%0u:%0u%0u:%0u%0u 20%0u%0u-%0u%0u-%0u%0u  OSC:%s CLKOUT:%0u", pcf8563_.reg.hour_10,
 | 
				
			||||||
 | 
					           pcf8563_.reg.hour, pcf8563_.reg.minute_10, pcf8563_.reg.minute, pcf8563_.reg.second_10, pcf8563_.reg.second,
 | 
				
			||||||
 | 
					           pcf8563_.reg.year_10, pcf8563_.reg.year, pcf8563_.reg.month_10, pcf8563_.reg.month, pcf8563_.reg.day_10,
 | 
				
			||||||
 | 
					           pcf8563_.reg.day, ONOFF(!pcf8563_.reg.stop), pcf8563_.reg.clkout_enabled);
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}  // namespace pcf8563
 | 
				
			||||||
 | 
					}  // namespace esphome
 | 
				
			||||||
							
								
								
									
										124
									
								
								esphome/components/pcf8563/pcf8563.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								esphome/components/pcf8563/pcf8563.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "esphome/core/component.h"
 | 
				
			||||||
 | 
					#include "esphome/components/i2c/i2c.h"
 | 
				
			||||||
 | 
					#include "esphome/components/time/real_time_clock.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace esphome {
 | 
				
			||||||
 | 
					namespace pcf8563 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PCF8563Component : public time::RealTimeClock, public i2c::I2CDevice {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  void setup() override;
 | 
				
			||||||
 | 
					  void update() override;
 | 
				
			||||||
 | 
					  void dump_config() override;
 | 
				
			||||||
 | 
					  float get_setup_priority() const override;
 | 
				
			||||||
 | 
					  void read_time();
 | 
				
			||||||
 | 
					  void write_time();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 protected:
 | 
				
			||||||
 | 
					  bool read_rtc_();
 | 
				
			||||||
 | 
					  bool write_rtc_();
 | 
				
			||||||
 | 
					  union PCF8563Reg {
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
 | 
					      // Control_1 register
 | 
				
			||||||
 | 
					      bool : 3;
 | 
				
			||||||
 | 
					      bool power_on_reset : 1;
 | 
				
			||||||
 | 
					      bool : 1;
 | 
				
			||||||
 | 
					      bool stop : 1;
 | 
				
			||||||
 | 
					      bool : 1;
 | 
				
			||||||
 | 
					      bool ext_test : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Control_2 register
 | 
				
			||||||
 | 
					      bool time_int : 1;
 | 
				
			||||||
 | 
					      bool alarm_int : 1;
 | 
				
			||||||
 | 
					      bool timer_flag : 1;
 | 
				
			||||||
 | 
					      bool alarm_flag : 1;
 | 
				
			||||||
 | 
					      bool timer_int_timer_pulse : 1;
 | 
				
			||||||
 | 
					      bool : 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Seconds register
 | 
				
			||||||
 | 
					      uint8_t second : 4;
 | 
				
			||||||
 | 
					      uint8_t second_10 : 3;
 | 
				
			||||||
 | 
					      bool clock_int : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Minutes register
 | 
				
			||||||
 | 
					      uint8_t minute : 4;
 | 
				
			||||||
 | 
					      uint8_t minute_10 : 3;
 | 
				
			||||||
 | 
					      uint8_t : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Hours register
 | 
				
			||||||
 | 
					      uint8_t hour : 4;
 | 
				
			||||||
 | 
					      uint8_t hour_10 : 2;
 | 
				
			||||||
 | 
					      uint8_t : 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Days register
 | 
				
			||||||
 | 
					      uint8_t day : 4;
 | 
				
			||||||
 | 
					      uint8_t day_10 : 2;
 | 
				
			||||||
 | 
					      uint8_t : 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Weekdays register
 | 
				
			||||||
 | 
					      uint8_t weekday : 3;
 | 
				
			||||||
 | 
					      uint8_t unused_3 : 5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Months register
 | 
				
			||||||
 | 
					      uint8_t month : 4;
 | 
				
			||||||
 | 
					      uint8_t month_10 : 1;
 | 
				
			||||||
 | 
					      uint8_t : 2;
 | 
				
			||||||
 | 
					      uint8_t century : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Years register
 | 
				
			||||||
 | 
					      uint8_t year : 4;
 | 
				
			||||||
 | 
					      uint8_t year_10 : 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Minute Alarm register
 | 
				
			||||||
 | 
					      uint8_t minute_alarm : 4;
 | 
				
			||||||
 | 
					      uint8_t minute_alarm_10 : 3;
 | 
				
			||||||
 | 
					      bool minute_alarm_enabled : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Hour Alarm register
 | 
				
			||||||
 | 
					      uint8_t hour_alarm : 4;
 | 
				
			||||||
 | 
					      uint8_t hour_alarm_10 : 2;
 | 
				
			||||||
 | 
					      uint8_t : 1;
 | 
				
			||||||
 | 
					      bool hour_alarm_enabled : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Day Alarm register
 | 
				
			||||||
 | 
					      uint8_t day_alarm : 4;
 | 
				
			||||||
 | 
					      uint8_t day_alarm_10 : 2;
 | 
				
			||||||
 | 
					      uint8_t : 1;
 | 
				
			||||||
 | 
					      bool day_alarm_enabled : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Weekday Alarm register
 | 
				
			||||||
 | 
					      uint8_t weekday_alarm : 3;
 | 
				
			||||||
 | 
					      uint8_t : 4;
 | 
				
			||||||
 | 
					      bool weekday_alarm_enabled : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // CLKout control register
 | 
				
			||||||
 | 
					      uint8_t frequency_output : 2;
 | 
				
			||||||
 | 
					      uint8_t : 5;
 | 
				
			||||||
 | 
					      uint8_t clkout_enabled : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Timer control register
 | 
				
			||||||
 | 
					      uint8_t timer_source_frequency : 2;
 | 
				
			||||||
 | 
					      uint8_t : 5;
 | 
				
			||||||
 | 
					      uint8_t timer_enabled : 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Timer register
 | 
				
			||||||
 | 
					      uint8_t countdown_period : 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } reg;
 | 
				
			||||||
 | 
					    mutable uint8_t raw[sizeof(reg)];
 | 
				
			||||||
 | 
					  } pcf8563_;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... Ts> class WriteAction : public Action<Ts...>, public Parented<PCF8563Component> {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  void play(Ts... x) override { this->parent_->write_time(); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... Ts> class ReadAction : public Action<Ts...>, public Parented<PCF8563Component> {
 | 
				
			||||||
 | 
					 public:
 | 
				
			||||||
 | 
					  void play(Ts... x) override { this->parent_->read_time(); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					}  // namespace pcf8563
 | 
				
			||||||
 | 
					}  // namespace esphome
 | 
				
			||||||
							
								
								
									
										62
									
								
								esphome/components/pcf8563/time.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								esphome/components/pcf8563/time.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					import esphome.config_validation as cv
 | 
				
			||||||
 | 
					import esphome.codegen as cg
 | 
				
			||||||
 | 
					from esphome import automation
 | 
				
			||||||
 | 
					from esphome.components import i2c, time
 | 
				
			||||||
 | 
					from esphome.const import CONF_ID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CODEOWNERS = ["@KoenBreeman"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEPENDENCIES = ["i2c"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pcf8563_ns = cg.esphome_ns.namespace("pcf8563")
 | 
				
			||||||
 | 
					pcf8563Component = pcf8563_ns.class_(
 | 
				
			||||||
 | 
					    "PCF8563Component", time.RealTimeClock, i2c.I2CDevice
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					WriteAction = pcf8563_ns.class_("WriteAction", automation.Action)
 | 
				
			||||||
 | 
					ReadAction = pcf8563_ns.class_("ReadAction", automation.Action)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cv.GenerateID(): cv.declare_id(pcf8563Component),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					).extend(i2c.i2c_device_schema(0xA3))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@automation.register_action(
 | 
				
			||||||
 | 
					    "pcf8563.write_time",
 | 
				
			||||||
 | 
					    WriteAction,
 | 
				
			||||||
 | 
					    automation.maybe_simple_id(
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            cv.GenerateID(): cv.use_id(pcf8563Component),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					async def pcf8563_write_time_to_code(config, action_id, template_arg, args):
 | 
				
			||||||
 | 
					    var = cg.new_Pvariable(action_id, template_arg)
 | 
				
			||||||
 | 
					    await cg.register_parented(var, config[CONF_ID])
 | 
				
			||||||
 | 
					    return var
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@automation.register_action(
 | 
				
			||||||
 | 
					    "pcf8563.read_time",
 | 
				
			||||||
 | 
					    ReadAction,
 | 
				
			||||||
 | 
					    automation.maybe_simple_id(
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            cv.GenerateID(): cv.use_id(pcf8563Component),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					async def pcf8563_read_time_to_code(config, action_id, template_arg, args):
 | 
				
			||||||
 | 
					    var = cg.new_Pvariable(action_id, template_arg)
 | 
				
			||||||
 | 
					    await cg.register_parented(var, config[CONF_ID])
 | 
				
			||||||
 | 
					    return var
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async def to_code(config):
 | 
				
			||||||
 | 
					    var = cg.new_Pvariable(config[CONF_ID])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await cg.register_component(var, config)
 | 
				
			||||||
 | 
					    await i2c.register_i2c_device(var, config)
 | 
				
			||||||
 | 
					    await time.register_time(var, config)
 | 
				
			||||||
@@ -590,6 +590,7 @@ display:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
time:
 | 
					time:
 | 
				
			||||||
  - platform: pcf85063
 | 
					  - platform: pcf85063
 | 
				
			||||||
 | 
					  - platform: pcf8563
 | 
				
			||||||
 | 
					
 | 
				
			||||||
text_sensor:
 | 
					text_sensor:
 | 
				
			||||||
  - platform: ezo_pmp
 | 
					  - platform: ezo_pmp
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user