-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support of Honeywell HumidIcon (I2C HIH series) Temperature & Hum…
…idity sensor (#5730)
- Loading branch information
1 parent
39bd829
commit c9c8d39
Showing
6 changed files
with
197 additions
and
0 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
"""Support for Honeywell HumidIcon HIH""" | ||
CODEOWNERS = ["@Benichou34"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Honeywell HumidIcon I2C Sensors | ||
// https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/humidity-with-temperature-sensors/common/documents/sps-siot-i2c-comms-humidicon-tn-009061-2-en-ciid-142171.pdf | ||
// | ||
|
||
#include "honeywell_hih.h" | ||
#include "esphome/core/log.h" | ||
|
||
namespace esphome { | ||
namespace honeywell_hih_i2c { | ||
|
||
static const char *const TAG = "honeywell_hih.i2c"; | ||
|
||
static const uint8_t REQUEST_CMD[1] = {0x00}; // Measurement Request Format | ||
static const uint16_t MAX_COUNT = 0x3FFE; // 2^14 - 2 | ||
|
||
void HoneywellHIComponent::read_sensor_data_() { | ||
uint8_t data[4]; | ||
|
||
if (this->read(data, sizeof(data)) != i2c::ERROR_OK) { | ||
ESP_LOGE(TAG, "Communication with Honeywell HIH failed!"); | ||
this->mark_failed(); | ||
return; | ||
} | ||
|
||
const uint16_t raw_humidity = (static_cast<uint16_t>(data[0] & 0x3F) << 8) | data[1]; | ||
float humidity = (static_cast<float>(raw_humidity) / MAX_COUNT) * 100; | ||
|
||
const uint16_t raw_temperature = (static_cast<uint16_t>(data[2]) << 6) | (data[3] >> 2); | ||
float temperature = (static_cast<float>(raw_temperature) / MAX_COUNT) * 165 - 40; | ||
|
||
ESP_LOGD(TAG, "Got temperature=%.2f°C humidity=%.2f%%", temperature, humidity); | ||
if (this->temperature_sensor_ != nullptr) | ||
this->temperature_sensor_->publish_state(temperature); | ||
if (this->humidity_sensor_ != nullptr) | ||
this->humidity_sensor_->publish_state(humidity); | ||
} | ||
|
||
void HoneywellHIComponent::start_measurement_() { | ||
if (this->write(REQUEST_CMD, sizeof(REQUEST_CMD)) != i2c::ERROR_OK) { | ||
ESP_LOGE(TAG, "Communication with Honeywell HIH failed!"); | ||
this->mark_failed(); | ||
return; | ||
} | ||
|
||
this->measurement_running_ = true; | ||
} | ||
|
||
bool HoneywellHIComponent::is_measurement_ready_() { | ||
uint8_t data[1]; | ||
|
||
if (this->read(data, sizeof(data)) != i2c::ERROR_OK) { | ||
ESP_LOGE(TAG, "Communication with Honeywell HIH failed!"); | ||
this->mark_failed(); | ||
return false; | ||
} | ||
|
||
// Check status bits | ||
return ((data[0] & 0xC0) == 0x00); | ||
} | ||
|
||
void HoneywellHIComponent::measurement_timeout_() { | ||
ESP_LOGE(TAG, "Honeywell HIH Timeout!"); | ||
this->measurement_running_ = false; | ||
this->mark_failed(); | ||
} | ||
|
||
void HoneywellHIComponent::update() { | ||
ESP_LOGV(TAG, "Update Honeywell HIH Sensor"); | ||
|
||
this->start_measurement_(); | ||
// The measurement cycle duration is typically 36.65 ms for temperature and humidity readings. | ||
this->set_timeout("meas_timeout", 100, [this] { this->measurement_timeout_(); }); | ||
} | ||
|
||
void HoneywellHIComponent::loop() { | ||
if (this->measurement_running_ && this->is_measurement_ready_()) { | ||
this->measurement_running_ = false; | ||
this->cancel_timeout("meas_timeout"); | ||
this->read_sensor_data_(); | ||
} | ||
} | ||
|
||
void HoneywellHIComponent::dump_config() { | ||
ESP_LOGD(TAG, "Honeywell HIH:"); | ||
LOG_I2C_DEVICE(this); | ||
if (this->is_failed()) { | ||
ESP_LOGE(TAG, "Communication with Honeywell HIH failed!"); | ||
} | ||
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_); | ||
LOG_SENSOR(" ", "Humidity", this->humidity_sensor_); | ||
LOG_UPDATE_INTERVAL(this); | ||
} | ||
|
||
float HoneywellHIComponent::get_setup_priority() const { return setup_priority::DATA; } | ||
|
||
} // namespace honeywell_hih_i2c | ||
} // namespace esphome |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Honeywell HumidIcon I2C Sensors | ||
#pragma once | ||
|
||
#include "esphome/core/component.h" | ||
#include "esphome/components/sensor/sensor.h" | ||
#include "esphome/components/i2c/i2c.h" | ||
|
||
namespace esphome { | ||
namespace honeywell_hih_i2c { | ||
|
||
class HoneywellHIComponent : public PollingComponent, public i2c::I2CDevice { | ||
public: | ||
void dump_config() override; | ||
float get_setup_priority() const override; | ||
void loop() override; | ||
void update() override; | ||
|
||
void set_temperature_sensor(sensor::Sensor *temperature_sensor) { this->temperature_sensor_ = temperature_sensor; } | ||
void set_humidity_sensor(sensor::Sensor *humidity_sensor) { this->humidity_sensor_ = humidity_sensor; } | ||
|
||
protected: | ||
bool measurement_running_{false}; | ||
sensor::Sensor *temperature_sensor_{nullptr}; | ||
sensor::Sensor *humidity_sensor_{nullptr}; | ||
|
||
private: | ||
void read_sensor_data_(); | ||
void start_measurement_(); | ||
bool is_measurement_ready_(); | ||
void measurement_timeout_(); | ||
}; | ||
|
||
} // namespace honeywell_hih_i2c | ||
} // namespace esphome |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import esphome.codegen as cg | ||
import esphome.config_validation as cv | ||
from esphome.components import i2c, sensor | ||
from esphome.const import ( | ||
CONF_HUMIDITY, | ||
CONF_ID, | ||
CONF_TEMPERATURE, | ||
STATE_CLASS_MEASUREMENT, | ||
UNIT_CELSIUS, | ||
UNIT_PERCENT, | ||
DEVICE_CLASS_TEMPERATURE, | ||
DEVICE_CLASS_HUMIDITY, | ||
) | ||
|
||
DEPENDENCIES = ["i2c"] | ||
|
||
honeywell_hih_ns = cg.esphome_ns.namespace("honeywell_hih_i2c") | ||
HONEYWELLHIComponent = honeywell_hih_ns.class_( | ||
"HoneywellHIComponent", cg.PollingComponent, i2c.I2CDevice | ||
) | ||
|
||
CONFIG_SCHEMA = ( | ||
cv.Schema( | ||
{ | ||
cv.GenerateID(): cv.declare_id(HONEYWELLHIComponent), | ||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema( | ||
unit_of_measurement=UNIT_CELSIUS, | ||
accuracy_decimals=1, | ||
device_class=DEVICE_CLASS_TEMPERATURE, | ||
state_class=STATE_CLASS_MEASUREMENT, | ||
), | ||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema( | ||
unit_of_measurement=UNIT_PERCENT, | ||
accuracy_decimals=1, | ||
device_class=DEVICE_CLASS_HUMIDITY, | ||
state_class=STATE_CLASS_MEASUREMENT, | ||
), | ||
} | ||
) | ||
.extend(cv.polling_component_schema("60s")) | ||
.extend(i2c.i2c_device_schema(0x27)) | ||
) | ||
|
||
|
||
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) | ||
|
||
if temperature_config := config.get(CONF_TEMPERATURE): | ||
sens = await sensor.new_sensor(temperature_config) | ||
cg.add(var.set_temperature_sensor(sens)) | ||
|
||
if humidity_config := config.get(CONF_HUMIDITY): | ||
sens = await sensor.new_sensor(humidity_config) | ||
cg.add(var.set_humidity_sensor(sens)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters