mirror of
https://github.com/esphome/esphome.git
synced 2026-05-26 03:07:04 +08:00
[dew_point] Add dew_point sensor component (#14441)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
This commit is contained in:
@@ -132,6 +132,7 @@ esphome/components/dashboard_import/* @esphome/core
|
||||
esphome/components/datetime/* @jesserockz @rfdarter
|
||||
esphome/components/debug/* @esphome/core
|
||||
esphome/components/delonghi/* @grob6000
|
||||
esphome/components/dew_point/* @CFlix
|
||||
esphome/components/dfplayer/* @glmnet
|
||||
esphome/components/dfrobot_sen0395/* @niklasweber
|
||||
esphome/components/dht/* @OttoWinter
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
CODEOWNERS = ["@CFlix"]
|
||||
@@ -0,0 +1,82 @@
|
||||
|
||||
#include "dew_point.h"
|
||||
|
||||
namespace esphome::dew_point {
|
||||
|
||||
static const char *const TAG = "dew_point.sensor";
|
||||
|
||||
void DewPointComponent::setup() {
|
||||
// Register callbacks for sensor updates
|
||||
if (this->temperature_sensor_ != nullptr) {
|
||||
this->temperature_sensor_->add_on_state_callback([this](float state) {
|
||||
this->temperature_value_ = state;
|
||||
this->enable_loop();
|
||||
});
|
||||
// Get initial value
|
||||
if (this->temperature_sensor_->has_state()) {
|
||||
this->temperature_value_ = this->temperature_sensor_->get_state();
|
||||
}
|
||||
}
|
||||
|
||||
if (this->humidity_sensor_ != nullptr) {
|
||||
this->humidity_sensor_->add_on_state_callback([this](float state) {
|
||||
this->humidity_value_ = state;
|
||||
this->enable_loop();
|
||||
});
|
||||
// Get initial value
|
||||
if (this->humidity_sensor_->has_state()) {
|
||||
this->humidity_value_ = this->humidity_sensor_->get_state();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DewPointComponent::dump_config() {
|
||||
LOG_SENSOR("", "Dew Point", this);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"Sources\n"
|
||||
" Temperature: '%s'\n"
|
||||
" Humidity: '%s'",
|
||||
this->temperature_sensor_->get_name().c_str(), this->humidity_sensor_->get_name().c_str());
|
||||
}
|
||||
|
||||
float DewPointComponent::get_setup_priority() const { return setup_priority::DATA; }
|
||||
|
||||
void DewPointComponent::loop() {
|
||||
// Only run once
|
||||
this->disable_loop();
|
||||
|
||||
// Check if we have valid values for both sensors
|
||||
if (std::isnan(this->temperature_value_) || std::isnan(this->humidity_value_)) {
|
||||
ESP_LOGW(TAG, "Temperature or humidity value is NaN, skipping calculation");
|
||||
this->publish_state(NAN);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for valid humidity range
|
||||
if (this->humidity_value_ <= 0.0f || this->humidity_value_ > 100.0f) {
|
||||
ESP_LOGW(TAG, "Humidity value out of range (0-100): %.2f", this->humidity_value_);
|
||||
this->publish_state(NAN);
|
||||
return;
|
||||
}
|
||||
|
||||
// Magnus formula constants
|
||||
const float a{17.625f};
|
||||
const float b{243.04f};
|
||||
|
||||
// Calculate dew point using Magnus formula
|
||||
// Td = (b * alpha) / (a - alpha)
|
||||
// where alpha = ln(RH/100) + (a * T) / (b + T)
|
||||
|
||||
const float alpha{std::log(this->humidity_value_ / 100.0f) +
|
||||
(a * this->temperature_value_) / (b + this->temperature_value_)};
|
||||
|
||||
const float dew_point{(b * alpha) / (a - alpha)};
|
||||
|
||||
// Publish the calculated dew point
|
||||
this->publish_state(dew_point);
|
||||
|
||||
ESP_LOGD(TAG, "'%s' >> %.1f°C (T: %.1f°C, RH: %.1f%%)", this->get_name().c_str(), dew_point, this->temperature_value_,
|
||||
this->humidity_value_);
|
||||
}
|
||||
|
||||
} // namespace esphome::dew_point
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
namespace esphome::dew_point {
|
||||
|
||||
class DewPointComponent : public Component, public sensor::Sensor {
|
||||
public:
|
||||
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; }
|
||||
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
void loop() override;
|
||||
|
||||
float get_setup_priority() const override;
|
||||
|
||||
protected:
|
||||
sensor::Sensor *temperature_sensor_{nullptr};
|
||||
sensor::Sensor *humidity_sensor_{nullptr};
|
||||
float temperature_value_{NAN};
|
||||
float humidity_value_{NAN};
|
||||
};
|
||||
|
||||
} // namespace esphome::dew_point
|
||||
@@ -0,0 +1,46 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import sensor
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_HUMIDITY,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
STATE_CLASS_MEASUREMENT,
|
||||
UNIT_CELSIUS,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["sensor"]
|
||||
|
||||
dew_point_ns = cg.esphome_ns.namespace("dew_point")
|
||||
DewPointComponent = dew_point_ns.class_(
|
||||
"DewPointComponent", cg.Component, sensor.Sensor
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(
|
||||
DewPointComponent,
|
||||
unit_of_measurement=UNIT_CELSIUS,
|
||||
accuracy_decimals=1,
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
icon="mdi:weather-rainy",
|
||||
)
|
||||
.extend(
|
||||
{
|
||||
cv.Required(CONF_TEMPERATURE): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_HUMIDITY): cv.use_id(sensor.Sensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await sensor.new_sensor(config)
|
||||
await cg.register_component(var, config)
|
||||
|
||||
temperature_sensor = await cg.get_variable(config[CONF_TEMPERATURE])
|
||||
cg.add(var.set_temperature_sensor(temperature_sensor))
|
||||
|
||||
humidity_sensor = await cg.get_variable(config[CONF_HUMIDITY])
|
||||
cg.add(var.set_humidity_sensor(humidity_sensor))
|
||||
@@ -0,0 +1,19 @@
|
||||
sensor:
|
||||
- platform: dew_point
|
||||
name: Dew Point
|
||||
temperature: template_temperature
|
||||
humidity: template_humidity
|
||||
- platform: template
|
||||
id: template_humidity
|
||||
lambda: |-
|
||||
if (millis() > 10000) {
|
||||
return 0.6;
|
||||
}
|
||||
return 0.0;
|
||||
- platform: template
|
||||
id: template_temperature
|
||||
lambda: |-
|
||||
if (millis() > 10000) {
|
||||
return 42.0;
|
||||
}
|
||||
return 0.0;
|
||||
@@ -0,0 +1 @@
|
||||
<<: !include common.yaml
|
||||
@@ -0,0 +1 @@
|
||||
<<: !include common.yaml
|
||||
@@ -0,0 +1 @@
|
||||
<<: !include common.yaml
|
||||
Reference in New Issue
Block a user