mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Add support for honeywellabp2 pressure sensor (#5422)
This commit is contained in:
		| @@ -122,6 +122,7 @@ esphome/components/hitachi_ac424/* @sourabhjaiswal | ||||
| esphome/components/hm3301/* @freekode | ||||
| esphome/components/homeassistant/* @OttoWinter | ||||
| esphome/components/honeywellabp/* @RubyBailey | ||||
| esphome/components/honeywellabp2_i2c/* @jpfaff | ||||
| esphome/components/host/* @esphome/core | ||||
| esphome/components/hrxl_maxsonar_wr/* @netmikey | ||||
| esphome/components/hte501/* @Stock-M | ||||
|   | ||||
							
								
								
									
										2
									
								
								esphome/components/honeywellabp2_i2c/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								esphome/components/honeywellabp2_i2c/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| """Support for Honeywell ABP2""" | ||||
| CODEOWNERS = ["@jpfaff"] | ||||
							
								
								
									
										108
									
								
								esphome/components/honeywellabp2_i2c/honeywellabp2.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								esphome/components/honeywellabp2_i2c/honeywellabp2.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| #include "honeywellabp2.h" | ||||
| #include "esphome/core/log.h" | ||||
| #include "esphome/core/helpers.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace honeywellabp2_i2c { | ||||
|  | ||||
| static const uint8_t STATUS_BIT_POWER = 6; | ||||
| static const uint8_t STATUS_BIT_BUSY = 5; | ||||
| static const uint8_t STATUS_BIT_ERROR = 2; | ||||
| static const uint8_t STATUS_MATH_SAT = 0; | ||||
|  | ||||
| static const char *const TAG = "honeywellabp2"; | ||||
|  | ||||
| void HONEYWELLABP2Sensor::read_sensor_data() { | ||||
|   if (this->read(raw_data_, 7) != i2c::ERROR_OK) { | ||||
|     ESP_LOGE(TAG, "Communication with ABP2 failed!"); | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
|   float press_counts = encode_uint24(raw_data_[1], raw_data_[2], raw_data_[3]);  // calculate digital pressure counts | ||||
|   float temp_counts = encode_uint24(raw_data_[4], raw_data_[5], raw_data_[6]);   // calculate digital temperature counts | ||||
|  | ||||
|   this->last_pressure_ = (((press_counts - this->min_count_) / (this->max_count_ - this->min_count_)) * | ||||
|                           (this->max_pressure_ - this->min_pressure_)) + | ||||
|                          this->min_pressure_; | ||||
|   this->last_temperature_ = (temp_counts * 200 / 16777215) - 50; | ||||
| } | ||||
|  | ||||
| void HONEYWELLABP2Sensor::start_measurement() { | ||||
|   if (this->write(i2c_cmd_, 3) != i2c::ERROR_OK) { | ||||
|     ESP_LOGE(TAG, "Communication with ABP2 failed!"); | ||||
|     this->mark_failed(); | ||||
|     return; | ||||
|   } | ||||
|   this->measurement_running_ = true; | ||||
| } | ||||
|  | ||||
| bool HONEYWELLABP2Sensor::is_measurement_ready() { | ||||
|   if (this->read(raw_data_, 1) != i2c::ERROR_OK) { | ||||
|     ESP_LOGE(TAG, "Communication with ABP2 failed!"); | ||||
|     this->mark_failed(); | ||||
|     return false; | ||||
|   } | ||||
|   if ((raw_data_[0] & (0x1 << STATUS_BIT_BUSY)) > 0) { | ||||
|     return false; | ||||
|   } | ||||
|   this->measurement_running_ = false; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| void HONEYWELLABP2Sensor::measurement_timeout() { | ||||
|   ESP_LOGE(TAG, "Timeout!"); | ||||
|   this->measurement_running_ = false; | ||||
|   this->mark_failed(); | ||||
| } | ||||
|  | ||||
| float HONEYWELLABP2Sensor::get_pressure() { return this->last_pressure_; } | ||||
|  | ||||
| float HONEYWELLABP2Sensor::get_temperature() { return this->last_temperature_; } | ||||
|  | ||||
| void HONEYWELLABP2Sensor::loop() { | ||||
|   if (this->measurement_running_) { | ||||
|     if (this->is_measurement_ready()) { | ||||
|       this->cancel_timeout("meas_timeout"); | ||||
|  | ||||
|       this->read_sensor_data(); | ||||
|       if (pressure_sensor_ != nullptr) { | ||||
|         this->pressure_sensor_->publish_state(this->get_pressure()); | ||||
|       } | ||||
|       if (temperature_sensor_ != nullptr) { | ||||
|         this->temperature_sensor_->publish_state(this->get_temperature()); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| void HONEYWELLABP2Sensor::update() { | ||||
|   ESP_LOGV(TAG, "Update Honeywell ABP2 Sensor"); | ||||
|  | ||||
|   this->start_measurement(); | ||||
|   this->set_timeout("meas_timeout", 50, [this] { this->measurement_timeout(); }); | ||||
| } | ||||
|  | ||||
| void HONEYWELLABP2Sensor::dump_config() { | ||||
|   ESP_LOGCONFIG(TAG, "  Min Pressure Range: %0.1f", this->min_pressure_); | ||||
|   ESP_LOGCONFIG(TAG, "  Max Pressure Range: %0.1f", this->max_pressure_); | ||||
|   if (this->transfer_function_ == ABP2_TRANS_FUNC_A) { | ||||
|     ESP_LOGCONFIG(TAG, "  Transfer function A"); | ||||
|   } else { | ||||
|     ESP_LOGCONFIG(TAG, "  Transfer function B"); | ||||
|   } | ||||
|   LOG_UPDATE_INTERVAL(this); | ||||
| } | ||||
|  | ||||
| void HONEYWELLABP2Sensor::set_transfer_function(ABP2TRANFERFUNCTION transfer_function) { | ||||
|   this->transfer_function_ = transfer_function; | ||||
|   if (this->transfer_function_ == ABP2_TRANS_FUNC_B) { | ||||
|     this->max_count_ = this->max_count_b_; | ||||
|     this->min_count_ = this->min_count_b_; | ||||
|   } else { | ||||
|     this->max_count_ = this->max_count_a_; | ||||
|     this->min_count_ = this->min_count_a_; | ||||
|   } | ||||
| } | ||||
|  | ||||
| }  // namespace honeywellabp2_i2c | ||||
| }  // namespace esphome | ||||
							
								
								
									
										60
									
								
								esphome/components/honeywellabp2_i2c/honeywellabp2.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								esphome/components/honeywellabp2_i2c/honeywellabp2.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| // for Honeywell ABP sensor | ||||
| // adapting code from https://github.com/vwls/Honeywell_pressure_sensors | ||||
| #pragma once | ||||
|  | ||||
| #include "esphome/components/sensor/sensor.h" | ||||
| #include "esphome/components/i2c/i2c.h" | ||||
| #include "esphome/core/hal.h" | ||||
| #include "esphome/core/component.h" | ||||
|  | ||||
| namespace esphome { | ||||
| namespace honeywellabp2_i2c { | ||||
|  | ||||
| enum ABP2TRANFERFUNCTION { ABP2_TRANS_FUNC_A = 0, ABP2_TRANS_FUNC_B = 1 }; | ||||
|  | ||||
| class HONEYWELLABP2Sensor : public PollingComponent, public i2c::I2CDevice { | ||||
|  public: | ||||
|   void set_pressure_sensor(sensor::Sensor *pressure_sensor) { this->pressure_sensor_ = pressure_sensor; }; | ||||
|   void set_temperature_sensor(sensor::Sensor *temperature_sensor) { this->temperature_sensor_ = temperature_sensor; }; | ||||
|   void loop() override; | ||||
|   void update() override; | ||||
|   float get_setup_priority() const override { return setup_priority::DATA; }; | ||||
|   void dump_config() override; | ||||
|  | ||||
|   void read_sensor_data(); | ||||
|   void start_measurement(); | ||||
|   bool is_measurement_ready(); | ||||
|   void measurement_timeout(); | ||||
|  | ||||
|   float get_pressure(); | ||||
|   float get_temperature(); | ||||
|  | ||||
|   void set_min_pressure(float min_pressure) { this->min_pressure_ = min_pressure; }; | ||||
|   void set_max_pressure(float max_pressure) { this->max_pressure_ = max_pressure; }; | ||||
|   void set_transfer_function(ABP2TRANFERFUNCTION transfer_function); | ||||
|  | ||||
|  protected: | ||||
|   float min_pressure_ = 0.0; | ||||
|   float max_pressure_ = 0.0; | ||||
|   ABP2TRANFERFUNCTION transfer_function_ = ABP2_TRANS_FUNC_A; | ||||
|  | ||||
|   sensor::Sensor *pressure_sensor_{nullptr}; | ||||
|   sensor::Sensor *temperature_sensor_{nullptr}; | ||||
|  | ||||
|   const float max_count_a_ = 15099494.4;  // (90% of 2^24 counts or 0xE66666) | ||||
|   const float min_count_a_ = 1677721.6;   // (10% of 2^24 counts or 0x19999A) | ||||
|   const float max_count_b_ = 11744051.2;  // (70% of 2^24 counts or 0xB33333) | ||||
|   const float min_count_b_ = 5033164.8;   // (30% of 2^24 counts or 0x4CCCCC) | ||||
|  | ||||
|   float max_count_; | ||||
|   float min_count_; | ||||
|   bool measurement_running_ = false; | ||||
|  | ||||
|   uint8_t raw_data_[7];                      // holds output data | ||||
|   uint8_t i2c_cmd_[3] = {0xAA, 0x00, 0x00};  // command to be sent | ||||
|   float last_pressure_; | ||||
|   float last_temperature_; | ||||
| }; | ||||
|  | ||||
| }  // namespace honeywellabp2_i2c | ||||
| }  // namespace esphome | ||||
							
								
								
									
										75
									
								
								esphome/components/honeywellabp2_i2c/sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								esphome/components/honeywellabp2_i2c/sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| import esphome.codegen as cg | ||||
| import esphome.config_validation as cv | ||||
| from esphome.components import sensor | ||||
| from esphome.components import i2c | ||||
| from esphome.const import ( | ||||
|     CONF_ID, | ||||
|     CONF_PRESSURE, | ||||
|     CONF_TEMPERATURE, | ||||
|     DEVICE_CLASS_PRESSURE, | ||||
|     DEVICE_CLASS_TEMPERATURE, | ||||
|     STATE_CLASS_MEASUREMENT, | ||||
|     UNIT_CELSIUS, | ||||
| ) | ||||
|  | ||||
| DEPENDENCIES = ["i2c"] | ||||
|  | ||||
| honeywellabp2_ns = cg.esphome_ns.namespace("honeywellabp2_i2c") | ||||
|  | ||||
| CONF_MIN_PRESSURE = "min_pressure" | ||||
| CONF_MAX_PRESSURE = "max_pressure" | ||||
| TRANSFER_FUNCTION = "transfer_function" | ||||
| ABP2TRANFERFUNCTION = honeywellabp2_ns.enum("ABP2TRANFERFUNCTION") | ||||
| TRANS_FUNC_OPTIONS = { | ||||
|     "A": ABP2TRANFERFUNCTION.ABP2_TRANS_FUNC_A, | ||||
|     "B": ABP2TRANFERFUNCTION.ABP2_TRANS_FUNC_B, | ||||
| } | ||||
|  | ||||
| HONEYWELLABP2Sensor = honeywellabp2_ns.class_( | ||||
|     "HONEYWELLABP2Sensor", sensor.Sensor, cg.PollingComponent, i2c.I2CDevice | ||||
| ) | ||||
|  | ||||
| CONFIG_SCHEMA = ( | ||||
|     cv.Schema( | ||||
|         { | ||||
|             cv.GenerateID(): cv.declare_id(HONEYWELLABP2Sensor), | ||||
|             cv.Optional(CONF_PRESSURE): sensor.sensor_schema( | ||||
|                 unit_of_measurement="Pa", | ||||
|                 accuracy_decimals=1, | ||||
|                 device_class=DEVICE_CLASS_PRESSURE, | ||||
|                 state_class=STATE_CLASS_MEASUREMENT, | ||||
|             ).extend( | ||||
|                 { | ||||
|                     cv.Required(CONF_MIN_PRESSURE): cv.float_, | ||||
|                     cv.Required(CONF_MAX_PRESSURE): cv.float_, | ||||
|                     cv.Required(TRANSFER_FUNCTION): cv.enum(TRANS_FUNC_OPTIONS), | ||||
|                 } | ||||
|             ), | ||||
|             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, | ||||
|             ), | ||||
|         } | ||||
|     ) | ||||
|     .extend(cv.polling_component_schema("60s")) | ||||
|     .extend(i2c.i2c_device_schema(0x28)) | ||||
| ) | ||||
|  | ||||
|  | ||||
| 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 pressure_config := config.get(CONF_PRESSURE): | ||||
|         sens = await sensor.new_sensor(pressure_config) | ||||
|         cg.add(var.set_pressure_sensor(sens)) | ||||
|         cg.add(var.set_min_pressure(pressure_config[CONF_MIN_PRESSURE])) | ||||
|         cg.add(var.set_max_pressure(pressure_config[CONF_MAX_PRESSURE])) | ||||
|         cg.add(var.set_transfer_function(pressure_config[TRANSFER_FUNCTION])) | ||||
|  | ||||
|     if temperature_config := config.get(CONF_TEMPERATURE): | ||||
|         sens = await sensor.new_sensor(temperature_config) | ||||
|         cg.add(var.set_temperature_sensor(sens)) | ||||
| @@ -742,6 +742,16 @@ sensor: | ||||
|     temperature: | ||||
|       name: Honeywell temperature | ||||
|     cs_pin: GPIO5 | ||||
|   - platform: honeywellabp2_i2c | ||||
|     pressure: | ||||
|       name: Honeywell2 pressure | ||||
|       min_pressure: 0 | ||||
|       max_pressure: 16000 | ||||
|       transfer_function: A | ||||
|     temperature: | ||||
|       name: Honeywell temperature | ||||
|     i2c_id: i2c_bus | ||||
|     address: 0x28 | ||||
|   - platform: hte501 | ||||
|     temperature: | ||||
|       name: Office Temperature 2 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user