mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Add sensor support: Honeywell ABP (SPI version) (#3164)
Co-authored-by: RubyBailey <ruby_bailey11@hotmail.com>
This commit is contained in:
		| @@ -80,6 +80,7 @@ esphome/components/hbridge/light/* @DotNetDann | |||||||
| esphome/components/heatpumpir/* @rob-deutsch | esphome/components/heatpumpir/* @rob-deutsch | ||||||
| esphome/components/hitachi_ac424/* @sourabhjaiswal | esphome/components/hitachi_ac424/* @sourabhjaiswal | ||||||
| esphome/components/homeassistant/* @OttoWinter | esphome/components/homeassistant/* @OttoWinter | ||||||
|  | esphome/components/honeywellabp/* @RubyBailey | ||||||
| esphome/components/hrxl_maxsonar_wr/* @netmikey | esphome/components/hrxl_maxsonar_wr/* @netmikey | ||||||
| esphome/components/i2c/* @esphome/core | esphome/components/i2c/* @esphome/core | ||||||
| esphome/components/improv_serial/* @esphome/core | esphome/components/improv_serial/* @esphome/core | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								esphome/components/honeywellabp/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								esphome/components/honeywellabp/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | """Support for Honeywell ABP""" | ||||||
							
								
								
									
										102
									
								
								esphome/components/honeywellabp/honeywellabp.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								esphome/components/honeywellabp/honeywellabp.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | |||||||
|  | #include "honeywellabp.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace honeywellabp { | ||||||
|  |  | ||||||
|  | static const char *const TAG = "honeywellabp"; | ||||||
|  |  | ||||||
|  | const float MIN_COUNT = 1638.4;   // 1638 counts (10% of 2^14 counts or 0x0666) | ||||||
|  | const float MAX_COUNT = 14745.6;  // 14745 counts (90% of 2^14 counts or 0x3999) | ||||||
|  |  | ||||||
|  | void HONEYWELLABPSensor::setup() { | ||||||
|  |   ESP_LOGD(TAG, "Setting up Honeywell ABP Sensor "); | ||||||
|  |   this->spi_setup(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint8_t HONEYWELLABPSensor::readsensor_() { | ||||||
|  |   // Polls the sensor for new data. | ||||||
|  |   // transfer 4 bytes (the last two are temperature only used by some sensors) | ||||||
|  |   this->enable(); | ||||||
|  |   buf_[0] = this->read_byte(); | ||||||
|  |   buf_[1] = this->read_byte(); | ||||||
|  |   buf_[2] = this->read_byte(); | ||||||
|  |   buf_[3] = this->read_byte(); | ||||||
|  |   this->disable(); | ||||||
|  |  | ||||||
|  |   // Check the status codes: | ||||||
|  |   // status = 0 : normal operation | ||||||
|  |   // status = 1 : device in command mode | ||||||
|  |   // status = 2 : stale data | ||||||
|  |   // status = 3 : diagnostic condition | ||||||
|  |   status_ = buf_[0] >> 6 & 0x3; | ||||||
|  |   ESP_LOGV(TAG, "Sensor status %d", status_); | ||||||
|  |  | ||||||
|  |   // if device is normal and there is new data, bitmask and save the raw data | ||||||
|  |   if (status_ == 0) { | ||||||
|  |     // 14 - bit pressure is the last 6 bits of byte 0 (high bits) & all of byte 1 (lowest 8 bits) | ||||||
|  |     pressure_count_ = ((uint16_t)(buf_[0]) << 8 & 0x3F00) | ((uint16_t)(buf_[1]) & 0xFF); | ||||||
|  |     // 11 - bit temperature is all of byte 2 (lowest 8 bits) and the first three bits of byte 3 | ||||||
|  |     temperature_count_ = (((uint16_t)(buf_[2]) << 3) & 0x7F8) | (((uint16_t)(buf_[3]) >> 5) & 0x7); | ||||||
|  |     ESP_LOGV(TAG, "Sensor pressure_count_ %d", pressure_count_); | ||||||
|  |     ESP_LOGV(TAG, "Sensor temperature_count_ %d", temperature_count_); | ||||||
|  |   } | ||||||
|  |   return status_; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // returns status | ||||||
|  | uint8_t HONEYWELLABPSensor::readstatus_() { return status_; } | ||||||
|  |  | ||||||
|  | // The pressure value from the most recent reading in raw counts | ||||||
|  | int HONEYWELLABPSensor::rawpressure_() { return pressure_count_; } | ||||||
|  |  | ||||||
|  | // The temperature value from the most recent reading in raw counts | ||||||
|  | int HONEYWELLABPSensor::rawtemperature_() { return temperature_count_; } | ||||||
|  |  | ||||||
|  | // Converts a digital pressure measurement in counts to pressure measured | ||||||
|  | float HONEYWELLABPSensor::countstopressure_(const int counts, const float min_pressure, const float max_pressure) { | ||||||
|  |   return ((((float) counts - MIN_COUNT) * (max_pressure - min_pressure)) / (MAX_COUNT - MIN_COUNT)) + min_pressure; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Converts a digital temperature measurement in counts to temperature in C | ||||||
|  | // This will be invalid if sensore daoes not have temperature measurement capability | ||||||
|  | float HONEYWELLABPSensor::countstotemperatures_(const int counts) { return (((float) counts / 2047.0) * 200.0) - 50.0; } | ||||||
|  |  | ||||||
|  | // Pressure value from the most recent reading in units | ||||||
|  | float HONEYWELLABPSensor::read_pressure_() { | ||||||
|  |   return countstopressure_(pressure_count_, honeywellabp_min_pressure_, honeywellabp_max_pressure_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Temperature value from the most recent reading in degrees C | ||||||
|  | float HONEYWELLABPSensor::read_temperature_() { return countstotemperatures_(temperature_count_); } | ||||||
|  |  | ||||||
|  | void HONEYWELLABPSensor::update() { | ||||||
|  |   ESP_LOGV(TAG, "Update Honeywell ABP Sensor"); | ||||||
|  |   if (readsensor_() == 0) { | ||||||
|  |     if (this->pressure_sensor_ != nullptr) | ||||||
|  |       this->pressure_sensor_->publish_state(read_pressure_() * 1.0); | ||||||
|  |     if (this->temperature_sensor_ != nullptr) | ||||||
|  |       this->temperature_sensor_->publish_state(read_temperature_() * 1.0); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | float HONEYWELLABPSensor::get_setup_priority() const { return setup_priority::LATE; } | ||||||
|  |  | ||||||
|  | void HONEYWELLABPSensor::dump_config() { | ||||||
|  |   //  LOG_SENSOR("", "HONEYWELLABP", this); | ||||||
|  |   LOG_PIN("  CS Pin: ", this->cs_); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Min Pressure Range: %0.1f", honeywellabp_min_pressure_); | ||||||
|  |   ESP_LOGCONFIG(TAG, "  Max Pressure Range: %0.1f", honeywellabp_max_pressure_); | ||||||
|  |   LOG_UPDATE_INTERVAL(this); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HONEYWELLABPSensor::set_honeywellabp_min_pressure(float min_pressure) { | ||||||
|  |   this->honeywellabp_min_pressure_ = min_pressure; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void HONEYWELLABPSensor::set_honeywellabp_max_pressure(float max_pressure) { | ||||||
|  |   this->honeywellabp_max_pressure_ = max_pressure; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace honeywellabp | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										45
									
								
								esphome/components/honeywellabp/honeywellabp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								esphome/components/honeywellabp/honeywellabp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | // 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/spi/spi.h" | ||||||
|  | #include "esphome/core/component.h" | ||||||
|  |  | ||||||
|  | namespace esphome { | ||||||
|  | namespace honeywellabp { | ||||||
|  |  | ||||||
|  | class HONEYWELLABPSensor : public PollingComponent, | ||||||
|  |                            public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, | ||||||
|  |                                                  spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_200KHZ> { | ||||||
|  |  public: | ||||||
|  |   void set_pressure_sensor(sensor::Sensor *pressure_sensor) { pressure_sensor_ = pressure_sensor; } | ||||||
|  |   void set_temperature_sensor(sensor::Sensor *temperature_sensor) { temperature_sensor_ = temperature_sensor; } | ||||||
|  |   void setup() override; | ||||||
|  |   void update() override; | ||||||
|  |   float get_setup_priority() const override; | ||||||
|  |   void dump_config() override; | ||||||
|  |   void set_honeywellabp_min_pressure(float min_pressure); | ||||||
|  |   void set_honeywellabp_max_pressure(float max_pressure); | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   float honeywellabp_min_pressure_ = 0.0; | ||||||
|  |   float honeywellabp_max_pressure_ = 0.0; | ||||||
|  |   uint8_t buf_[4];             // buffer to hold sensor data | ||||||
|  |   uint8_t status_ = 0;         // byte to hold status information. | ||||||
|  |   int pressure_count_ = 0;     // hold raw pressure data (14 - bit, 0 - 16384) | ||||||
|  |   int temperature_count_ = 0;  // hold raw temperature data (11 - bit, 0 - 2048) | ||||||
|  |   sensor::Sensor *pressure_sensor_; | ||||||
|  |   sensor::Sensor *temperature_sensor_; | ||||||
|  |   uint8_t readsensor_(); | ||||||
|  |   uint8_t readstatus_(); | ||||||
|  |   int rawpressure_(); | ||||||
|  |   int rawtemperature_(); | ||||||
|  |   float countstopressure_(int counts, float min_pressure, float max_pressure); | ||||||
|  |   float countstotemperatures_(int counts); | ||||||
|  |   float read_pressure_(); | ||||||
|  |   float read_temperature_(); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace honeywellabp | ||||||
|  | }  // namespace esphome | ||||||
							
								
								
									
										70
									
								
								esphome/components/honeywellabp/sensor.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								esphome/components/honeywellabp/sensor.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | import esphome.codegen as cg | ||||||
|  | import esphome.config_validation as cv | ||||||
|  | from esphome.components import sensor | ||||||
|  | from esphome.components import spi | ||||||
|  | from esphome.const import ( | ||||||
|  |     CONF_ID, | ||||||
|  |     CONF_PRESSURE, | ||||||
|  |     CONF_TEMPERATURE, | ||||||
|  |     DEVICE_CLASS_PRESSURE, | ||||||
|  |     DEVICE_CLASS_TEMPERATURE, | ||||||
|  |     STATE_CLASS_MEASUREMENT, | ||||||
|  |     UNIT_CELSIUS, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | DEPENDENCIES = ["spi"] | ||||||
|  | CODEOWNERS = ["@RubyBailey"] | ||||||
|  |  | ||||||
|  | CONF_MIN_PRESSURE = "min_pressure" | ||||||
|  | CONF_MAX_PRESSURE = "max_pressure" | ||||||
|  |  | ||||||
|  | honeywellabp_ns = cg.esphome_ns.namespace("honeywellabp") | ||||||
|  | HONEYWELLABPSensor = honeywellabp_ns.class_( | ||||||
|  |     "HONEYWELLABPSensor", sensor.Sensor, cg.PollingComponent, spi.SPIDevice | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | CONFIG_SCHEMA = ( | ||||||
|  |     cv.Schema( | ||||||
|  |         { | ||||||
|  |             cv.GenerateID(): cv.declare_id(HONEYWELLABPSensor), | ||||||
|  |             cv.Optional(CONF_PRESSURE): sensor.sensor_schema( | ||||||
|  |                 unit_of_measurement="psi", | ||||||
|  |                 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.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(spi.spi_device_schema(cs_pin_required=True)) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async def to_code(config): | ||||||
|  |  | ||||||
|  |     var = cg.new_Pvariable(config[CONF_ID]) | ||||||
|  |     await cg.register_component(var, config) | ||||||
|  |     await spi.register_spi_device(var, config) | ||||||
|  |  | ||||||
|  |     if CONF_PRESSURE in config: | ||||||
|  |         conf = config[CONF_PRESSURE] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_pressure_sensor(sens)) | ||||||
|  |         cg.add(var.set_honeywellabp_min_pressure(conf[CONF_MIN_PRESSURE])) | ||||||
|  |         cg.add(var.set_honeywellabp_max_pressure(conf[CONF_MAX_PRESSURE])) | ||||||
|  |  | ||||||
|  |     if CONF_TEMPERATURE in config: | ||||||
|  |         conf = config[CONF_TEMPERATURE] | ||||||
|  |         sens = await sensor.new_sensor(conf) | ||||||
|  |         cg.add(var.set_temperature_sensor(sens)) | ||||||
| @@ -600,6 +600,14 @@ sensor: | |||||||
|     oversampling: 8x |     oversampling: 8x | ||||||
|     update_interval: 15s |     update_interval: 15s | ||||||
|     i2c_id: i2c_bus |     i2c_id: i2c_bus | ||||||
|  |   - platform: honeywellabp | ||||||
|  |     pressure: | ||||||
|  |       name: "Honeywell pressure" | ||||||
|  |       min_pressure: 0 | ||||||
|  |       max_pressure: 15 | ||||||
|  |     temperature: | ||||||
|  |       name: "Honeywell temperature" | ||||||
|  |     cs_pin: GPIO5 | ||||||
|   - platform: qmc5883l |   - platform: qmc5883l | ||||||
|     address: 0x0D |     address: 0x0D | ||||||
|     field_strength_x: |     field_strength_x: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user