mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 00:18:11 +01:00
Add support for honeywellabp2 pressure sensor (#5422)
This commit is contained in:
parent
ec835c0b05
commit
2895cc6c57
6 changed files with 256 additions and 0 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue