mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 00:18:11 +01:00
Add sensor support: Honeywell ABP (SPI version) (#3164)
Co-authored-by: RubyBailey <ruby_bailey11@hotmail.com>
This commit is contained in:
parent
68b3fd6b8f
commit
c9094ca537
6 changed files with 227 additions and 0 deletions
|
@ -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:
|
||||||
|
|
Loading…
Reference in a new issue