mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 06:33:51 +00:00 
			
		
		
		
	add heating functionality to SI7021 (#4828)
* add heating functoinality * add test * add heat * fix * fix * fix * fix * fix * fix sensor * restore class * Update esphome/components/htu21d/sensor.py * Update esphome/components/htu21d/sensor.py Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> * Update esphome/components/htu21d/sensor.py Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --------- Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
This commit is contained in:
		| @@ -11,7 +11,11 @@ static const uint8_t HTU21D_ADDRESS = 0x40; | ||||
| static const uint8_t HTU21D_REGISTER_RESET = 0xFE; | ||||
| static const uint8_t HTU21D_REGISTER_TEMPERATURE = 0xF3; | ||||
| static const uint8_t HTU21D_REGISTER_HUMIDITY = 0xF5; | ||||
| static const uint8_t HTU21D_WRITERHT_REG_CMD = 0xE6; /**< Write RH/T User Register 1 */ | ||||
| static const uint8_t HTU21D_REGISTER_STATUS = 0xE7; | ||||
| static const uint8_t HTU21D_WRITEHEATER_REG_CMD = 0x51; /**< Write Heater Control Register */ | ||||
| static const uint8_t HTU21D_READHEATER_REG_CMD = 0x11;  /**< Read Heater Control Register */ | ||||
| static const uint8_t HTU21D_REG_HTRE_BIT = 0x02;        /**< Control Register Heater Bit */ | ||||
|  | ||||
| void HTU21DComponent::setup() { | ||||
|   ESP_LOGCONFIG(TAG, "Setting up HTU21D..."); | ||||
| @@ -62,14 +66,66 @@ void HTU21DComponent::update() { | ||||
|   raw_humidity = i2c::i2ctohs(raw_humidity); | ||||
|  | ||||
|   float humidity = (float(raw_humidity & 0xFFFC)) * 125.0f / 65536.0f - 6.0f; | ||||
|   ESP_LOGD(TAG, "Got Temperature=%.1f°C Humidity=%.1f%%", temperature, humidity); | ||||
|  | ||||
|   int8_t heater_level = this->get_heater_level(); | ||||
|  | ||||
|   ESP_LOGD(TAG, "Got Temperature=%.1f°C Humidity=%.1f%% Heater Level=%d", temperature, humidity, heater_level); | ||||
|  | ||||
|   if (this->temperature_ != nullptr) | ||||
|     this->temperature_->publish_state(temperature); | ||||
|   if (this->humidity_ != nullptr) | ||||
|     this->humidity_->publish_state(humidity); | ||||
|   if (this->heater_ != nullptr) | ||||
|     this->heater_->publish_state(humidity); | ||||
|   this->status_clear_warning(); | ||||
| } | ||||
|  | ||||
| bool HTU21DComponent::is_heater_enabled() { | ||||
|   uint8_t raw_heater; | ||||
|   if (this->read_register(HTU21D_REGISTER_STATUS, reinterpret_cast<uint8_t *>(&raw_heater), 2) != i2c::ERROR_OK) { | ||||
|     this->status_set_warning(); | ||||
|     return false; | ||||
|   } | ||||
|   raw_heater = i2c::i2ctohs(raw_heater); | ||||
|   return (bool) (((raw_heater) >> (HTU21D_REG_HTRE_BIT)) & 0x01); | ||||
| } | ||||
|  | ||||
| void HTU21DComponent::set_heater(bool status) { | ||||
|   uint8_t raw_heater; | ||||
|   if (this->read_register(HTU21D_REGISTER_STATUS, reinterpret_cast<uint8_t *>(&raw_heater), 2) != i2c::ERROR_OK) { | ||||
|     this->status_set_warning(); | ||||
|     return; | ||||
|   } | ||||
|   raw_heater = i2c::i2ctohs(raw_heater); | ||||
|   if (status) { | ||||
|     raw_heater |= (1 << (HTU21D_REG_HTRE_BIT)); | ||||
|   } else { | ||||
|     raw_heater &= ~(1 << (HTU21D_REG_HTRE_BIT)); | ||||
|   } | ||||
|  | ||||
|   if (this->write_register(HTU21D_WRITERHT_REG_CMD, &raw_heater, 1) != i2c::ERROR_OK) { | ||||
|     this->status_set_warning(); | ||||
|     return; | ||||
|   } | ||||
| } | ||||
|  | ||||
| void HTU21DComponent::set_heater_level(uint8_t level) { | ||||
|   if (this->write_register(HTU21D_WRITEHEATER_REG_CMD, &level, 1) != i2c::ERROR_OK) { | ||||
|     this->status_set_warning(); | ||||
|     return; | ||||
|   } | ||||
| } | ||||
|  | ||||
| int8_t HTU21DComponent::get_heater_level() { | ||||
|   int8_t raw_heater; | ||||
|   if (this->read_register(HTU21D_READHEATER_REG_CMD, reinterpret_cast<uint8_t *>(&raw_heater), 2) != i2c::ERROR_OK) { | ||||
|     this->status_set_warning(); | ||||
|     return 0; | ||||
|   } | ||||
|   raw_heater = i2c::i2ctohs(raw_heater); | ||||
|   return raw_heater; | ||||
| } | ||||
|  | ||||
| float HTU21DComponent::get_setup_priority() const { return setup_priority::DATA; } | ||||
|  | ||||
| }  // namespace htu21d | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| #include "esphome/core/component.h" | ||||
| #include "esphome/components/sensor/sensor.h" | ||||
| #include "esphome/components/i2c/i2c.h" | ||||
| #include "esphome/core/automation.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace htu21d { | ||||
| @@ -11,6 +12,7 @@ class HTU21DComponent : public PollingComponent, public i2c::I2CDevice { | ||||
|  public: | ||||
|   void set_temperature(sensor::Sensor *temperature) { temperature_ = temperature; } | ||||
|   void set_humidity(sensor::Sensor *humidity) { humidity_ = humidity; } | ||||
|   void set_heater(sensor::Sensor *heater) { heater_ = heater; } | ||||
|  | ||||
|   /// Setup (reset) the sensor and check connection. | ||||
|   void setup() override; | ||||
| @@ -18,11 +20,39 @@ class HTU21DComponent : public PollingComponent, public i2c::I2CDevice { | ||||
|   /// Update the sensor values (temperature+humidity). | ||||
|   void update() override; | ||||
|  | ||||
|   bool is_heater_enabled(); | ||||
|   void set_heater(bool status); | ||||
|   void set_heater_level(uint8_t level); | ||||
|   int8_t get_heater_level(); | ||||
|  | ||||
|   float get_setup_priority() const override; | ||||
|  | ||||
|  protected: | ||||
|   sensor::Sensor *temperature_{nullptr}; | ||||
|   sensor::Sensor *humidity_{nullptr}; | ||||
|   sensor::Sensor *heater_{nullptr}; | ||||
| }; | ||||
|  | ||||
| template<typename... Ts> class SetHeaterLevelAction : public Action<Ts...>, public Parented<HTU21DComponent> { | ||||
|  public: | ||||
|   TEMPLATABLE_VALUE(uint8_t, level) | ||||
|  | ||||
|   void play(Ts... x) override { | ||||
|     auto level = this->level_.value(x...); | ||||
|  | ||||
|     this->parent_->set_heater_level(level); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template<typename... Ts> class SetHeaterAction : public Action<Ts...>, public Parented<HTU21DComponent> { | ||||
|  public: | ||||
|   TEMPLATABLE_VALUE(bool, status) | ||||
|  | ||||
|   void play(Ts... x) override { | ||||
|     auto status = this->status_.value(x...); | ||||
|  | ||||
|     this->parent_->set_heater(status); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| }  // namespace htu21d | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import i2c, sensor | ||||
| from esphome import automation | ||||
| from esphome.const import ( | ||||
|     CONF_HUMIDITY, | ||||
|     CONF_ID, | ||||
| @@ -10,6 +11,10 @@ from esphome.const import ( | ||||
|     STATE_CLASS_MEASUREMENT, | ||||
|     UNIT_CELSIUS, | ||||
|     UNIT_PERCENT, | ||||
|     CONF_HEATER, | ||||
|     UNIT_EMPTY, | ||||
|     CONF_LEVEL, | ||||
|     CONF_STATUS, | ||||
| ) | ||||
|  | ||||
| DEPENDENCIES = ["i2c"] | ||||
| @@ -19,6 +24,10 @@ HTU21DComponent = htu21d_ns.class_( | ||||
|     "HTU21DComponent", cg.PollingComponent, i2c.I2CDevice | ||||
| ) | ||||
|  | ||||
| SetHeaterLevelAction = htu21d_ns.class_("SetHeaterLevelAction", automation.Action) | ||||
| SetHeaterAction = htu21d_ns.class_("SetHeaterAction", automation.Action) | ||||
|  | ||||
|  | ||||
| CONFIG_SCHEMA = ( | ||||
|     cv.Schema( | ||||
|         { | ||||
| @@ -35,6 +44,11 @@ CONFIG_SCHEMA = ( | ||||
|                 device_class=DEVICE_CLASS_HUMIDITY, | ||||
|                 state_class=STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|             cv.Optional(CONF_HEATER): sensor.sensor_schema( | ||||
|                 unit_of_measurement=UNIT_EMPTY, | ||||
|                 accuracy_decimals=1, | ||||
|                 state_class=STATE_CLASS_MEASUREMENT, | ||||
|             ), | ||||
|         } | ||||
|     ) | ||||
|     .extend(cv.polling_component_schema("60s")) | ||||
| @@ -54,3 +68,45 @@ async def to_code(config): | ||||
|     if CONF_HUMIDITY in config: | ||||
|         sens = await sensor.new_sensor(config[CONF_HUMIDITY]) | ||||
|         cg.add(var.set_humidity(sens)) | ||||
|  | ||||
|     if CONF_HEATER in config: | ||||
|         sens = await sensor.new_sensor(config[CONF_HEATER]) | ||||
|         cg.add(var.set_heater(sens)) | ||||
|  | ||||
|  | ||||
| @automation.register_action( | ||||
|     "htu21d.set_heater_level", | ||||
|     SetHeaterLevelAction, | ||||
|     cv.maybe_simple_value( | ||||
|         { | ||||
|             cv.GenerateID(): cv.use_id(HTU21DComponent), | ||||
|             cv.Required(CONF_LEVEL): cv.templatable(cv.int_), | ||||
|         }, | ||||
|         key=CONF_LEVEL, | ||||
|     ), | ||||
| ) | ||||
| async def set_heater_level_to_code(config, action_id, template_arg, args): | ||||
|     var = cg.new_Pvariable(action_id, template_arg) | ||||
|     await cg.register_parented(var, config[CONF_ID]) | ||||
|     level_ = await cg.templatable(config[CONF_LEVEL], args, int) | ||||
|     cg.add(var.set_level(level_)) | ||||
|     return var | ||||
|  | ||||
|  | ||||
| @automation.register_action( | ||||
|     "htu21d.set_heater", | ||||
|     SetHeaterAction, | ||||
|     cv.maybe_simple_value( | ||||
|         { | ||||
|             cv.GenerateID(): cv.use_id(HTU21DComponent), | ||||
|             cv.Required(CONF_STATUS): cv.templatable(cv.boolean), | ||||
|         }, | ||||
|         key=CONF_STATUS, | ||||
|     ), | ||||
| ) | ||||
| async def set_heater_to_code(config, action_id, template_arg, args): | ||||
|     var = cg.new_Pvariable(action_id, template_arg) | ||||
|     await cg.register_parented(var, config[CONF_ID]) | ||||
|     status_ = await cg.templatable(config[CONF_LEVEL], args, bool) | ||||
|     cg.add(var.set_status(status_)) | ||||
|     return var | ||||
|   | ||||
| @@ -848,6 +848,8 @@ sensor: | ||||
|       name: Living Room Temperature 6 | ||||
|     humidity: | ||||
|       name: Living Room Humidity 6 | ||||
|     heater: | ||||
|       name: Living Room Heater 6 | ||||
|     update_interval: 15s | ||||
|     i2c_id: i2c_bus | ||||
|   - platform: max6675 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user