mirror of
https://github.com/esphome/esphome.git
synced 2024-12-23 05:54:56 +01:00
Base climate ir (#726)
* add ClimateIR * update climate ir * update class comment * lint * moved to climate_ir * fix include path * use climateir * updates * update include path * lint * fixed variable assigned to itself
This commit is contained in:
parent
1242f43769
commit
578e5a0d7a
6 changed files with 121 additions and 82 deletions
0
esphome/components/climate_ir/__init__.py
Normal file
0
esphome/components/climate_ir/__init__.py
Normal file
57
esphome/components/climate_ir/climate_ir.cpp
Normal file
57
esphome/components/climate_ir/climate_ir.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "climate_ir.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace climate {
|
||||
|
||||
climate::ClimateTraits ClimateIR::traits() {
|
||||
auto traits = climate::ClimateTraits();
|
||||
traits.set_supports_current_temperature(this->sensor_ != nullptr);
|
||||
traits.set_supports_auto_mode(true);
|
||||
traits.set_supports_cool_mode(this->supports_cool_);
|
||||
traits.set_supports_heat_mode(this->supports_heat_);
|
||||
traits.set_supports_two_point_target_temperature(false);
|
||||
traits.set_supports_away(false);
|
||||
traits.set_visual_min_temperature(this->minimum_temperature_);
|
||||
traits.set_visual_max_temperature(this->maximum_temperature_);
|
||||
traits.set_visual_temperature_step(this->temperature_step_);
|
||||
return traits;
|
||||
}
|
||||
|
||||
void ClimateIR::setup() {
|
||||
if (this->sensor_) {
|
||||
this->sensor_->add_on_state_callback([this](float state) {
|
||||
this->current_temperature = state;
|
||||
// current temperature changed, publish state
|
||||
this->publish_state();
|
||||
});
|
||||
this->current_temperature = this->sensor_->state;
|
||||
} else
|
||||
this->current_temperature = NAN;
|
||||
// restore set points
|
||||
auto restore = this->restore_state_();
|
||||
if (restore.has_value()) {
|
||||
restore->apply(this);
|
||||
} else {
|
||||
// restore from defaults
|
||||
this->mode = climate::CLIMATE_MODE_OFF;
|
||||
// initialize target temperature to some value so that it's not NAN
|
||||
this->target_temperature =
|
||||
roundf(clamp(this->current_temperature, this->minimum_temperature_, this->maximum_temperature_));
|
||||
}
|
||||
// Never send nan to HA
|
||||
if (isnan(this->target_temperature))
|
||||
this->target_temperature = 24;
|
||||
}
|
||||
|
||||
void ClimateIR::control(const climate::ClimateCall &call) {
|
||||
if (call.get_mode().has_value())
|
||||
this->mode = *call.get_mode();
|
||||
if (call.get_target_temperature().has_value())
|
||||
this->target_temperature = *call.get_target_temperature();
|
||||
|
||||
this->transmit_state();
|
||||
this->publish_state();
|
||||
}
|
||||
|
||||
} // namespace climate
|
||||
} // namespace esphome
|
53
esphome/components/climate_ir/climate_ir.h
Normal file
53
esphome/components/climate_ir/climate_ir.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/climate/climate.h"
|
||||
#include "esphome/components/remote_base/remote_base.h"
|
||||
#include "esphome/components/remote_transmitter/remote_transmitter.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace climate {
|
||||
|
||||
/* A base for climate which works by sending (and receiving) IR codes
|
||||
|
||||
To send IR codes implement
|
||||
void ClimateIR::transmit_state_()
|
||||
|
||||
Likewise to decode a IR into the AC state, implement
|
||||
bool RemoteReceiverListener::on_receive(remote_base::RemoteReceiveData data) and return true
|
||||
*/
|
||||
class ClimateIR : public climate::Climate, public Component, public remote_base::RemoteReceiverListener {
|
||||
public:
|
||||
ClimateIR(float minimum_temperature, float maximum_temperature, float temperature_step = 1.0f) {
|
||||
this->minimum_temperature_ = minimum_temperature;
|
||||
this->maximum_temperature_ = maximum_temperature;
|
||||
this->temperature_step_ = temperature_step;
|
||||
}
|
||||
|
||||
void setup() override;
|
||||
void set_transmitter(remote_transmitter::RemoteTransmitterComponent *transmitter) {
|
||||
this->transmitter_ = transmitter;
|
||||
}
|
||||
void set_supports_cool(bool supports_cool) { this->supports_cool_ = supports_cool; }
|
||||
void set_supports_heat(bool supports_heat) { this->supports_heat_ = supports_heat; }
|
||||
void set_sensor(sensor::Sensor *sensor) { this->sensor_ = sensor; }
|
||||
|
||||
protected:
|
||||
float minimum_temperature_, maximum_temperature_, temperature_step_;
|
||||
|
||||
/// Override control to change settings of the climate device.
|
||||
void control(const climate::ClimateCall &call) override;
|
||||
/// Return the traits of this controller.
|
||||
climate::ClimateTraits traits() override;
|
||||
|
||||
/// Transmit via IR the state of this climate controller.
|
||||
virtual void transmit_state() {}
|
||||
|
||||
bool supports_cool_{true};
|
||||
bool supports_heat_{true};
|
||||
|
||||
remote_transmitter::RemoteTransmitterComponent *transmitter_;
|
||||
sensor::Sensor *sensor_{nullptr};
|
||||
};
|
||||
} // namespace climate
|
||||
} // namespace esphome
|
|
@ -3,7 +3,7 @@ import esphome.config_validation as cv
|
|||
from esphome.components import climate, remote_transmitter, remote_receiver, sensor
|
||||
from esphome.const import CONF_ID, CONF_SENSOR
|
||||
|
||||
AUTO_LOAD = ['sensor']
|
||||
AUTO_LOAD = ['sensor', 'climate_ir']
|
||||
|
||||
coolix_ns = cg.esphome_ns.namespace('coolix')
|
||||
CoolixClimate = coolix_ns.class_('CoolixClimate', climate.Climate, cg.Component)
|
||||
|
|
|
@ -27,8 +27,6 @@ const uint32_t COOLIX_FAN_MED = 0x5000;
|
|||
const uint32_t COOLIX_FAN_MAX = 0x3000;
|
||||
|
||||
// Temperature
|
||||
const uint8_t COOLIX_TEMP_MIN = 17; // Celsius
|
||||
const uint8_t COOLIX_TEMP_MAX = 30; // Celsius
|
||||
const uint8_t COOLIX_TEMP_RANGE = COOLIX_TEMP_MAX - COOLIX_TEMP_MIN + 1;
|
||||
const uint8_t COOLIX_FAN_TEMP_CODE = 0b1110; // Part of Fan Mode.
|
||||
const uint32_t COOLIX_TEMP_MASK = 0b11110000;
|
||||
|
@ -60,56 +58,7 @@ static const uint32_t FOOTER_SPACE_US = HEADER_SPACE_US;
|
|||
|
||||
const uint16_t COOLIX_BITS = 24;
|
||||
|
||||
climate::ClimateTraits CoolixClimate::traits() {
|
||||
auto traits = climate::ClimateTraits();
|
||||
traits.set_supports_current_temperature(this->sensor_ != nullptr);
|
||||
traits.set_supports_auto_mode(true);
|
||||
traits.set_supports_cool_mode(this->supports_cool_);
|
||||
traits.set_supports_heat_mode(this->supports_heat_);
|
||||
traits.set_supports_two_point_target_temperature(false);
|
||||
traits.set_supports_away(false);
|
||||
traits.set_visual_min_temperature(17);
|
||||
traits.set_visual_max_temperature(30);
|
||||
traits.set_visual_temperature_step(1);
|
||||
return traits;
|
||||
}
|
||||
|
||||
void CoolixClimate::setup() {
|
||||
if (this->sensor_) {
|
||||
this->sensor_->add_on_state_callback([this](float state) {
|
||||
this->current_temperature = state;
|
||||
// current temperature changed, publish state
|
||||
this->publish_state();
|
||||
});
|
||||
this->current_temperature = this->sensor_->state;
|
||||
} else
|
||||
this->current_temperature = NAN;
|
||||
// restore set points
|
||||
auto restore = this->restore_state_();
|
||||
if (restore.has_value()) {
|
||||
restore->apply(this);
|
||||
} else {
|
||||
// restore from defaults
|
||||
this->mode = climate::CLIMATE_MODE_OFF;
|
||||
// initialize target temperature to some value so that it's not NAN
|
||||
this->target_temperature = (uint8_t) roundf(clamp(this->current_temperature, COOLIX_TEMP_MIN, COOLIX_TEMP_MAX));
|
||||
}
|
||||
// never send nan as temperature. HA will disable the user to change the temperature.
|
||||
if (isnan(this->target_temperature))
|
||||
this->target_temperature = 24;
|
||||
}
|
||||
|
||||
void CoolixClimate::control(const climate::ClimateCall &call) {
|
||||
if (call.get_mode().has_value())
|
||||
this->mode = *call.get_mode();
|
||||
if (call.get_target_temperature().has_value())
|
||||
this->target_temperature = *call.get_target_temperature();
|
||||
|
||||
this->transmit_state_();
|
||||
this->publish_state();
|
||||
}
|
||||
|
||||
void CoolixClimate::transmit_state_() {
|
||||
void CoolixClimate::transmit_state() {
|
||||
uint32_t remote_state;
|
||||
|
||||
switch (this->mode) {
|
||||
|
|
|
@ -1,43 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/components/climate/climate.h"
|
||||
#include "esphome/components/remote_base/remote_base.h"
|
||||
#include "esphome/components/remote_transmitter/remote_transmitter.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/climate_ir/climate_ir.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace coolix {
|
||||
|
||||
using namespace remote_base;
|
||||
// Temperature
|
||||
const uint8_t COOLIX_TEMP_MIN = 17; // Celsius
|
||||
const uint8_t COOLIX_TEMP_MAX = 30; // Celsius
|
||||
|
||||
class CoolixClimate : public climate::Climate, public Component, public RemoteReceiverListener {
|
||||
class CoolixClimate : public climate::ClimateIR {
|
||||
public:
|
||||
void setup() override;
|
||||
void set_transmitter(remote_transmitter::RemoteTransmitterComponent *transmitter) {
|
||||
this->transmitter_ = transmitter;
|
||||
}
|
||||
void set_supports_cool(bool supports_cool) { this->supports_cool_ = supports_cool; }
|
||||
void set_supports_heat(bool supports_heat) { this->supports_heat_ = supports_heat; }
|
||||
void set_sensor(sensor::Sensor *sensor) { this->sensor_ = sensor; }
|
||||
CoolixClimate() : climate::ClimateIR(COOLIX_TEMP_MIN, COOLIX_TEMP_MAX) {}
|
||||
|
||||
protected:
|
||||
/// Override control to change settings of the climate device.
|
||||
void control(const climate::ClimateCall &call) override;
|
||||
/// Return the traits of this controller.
|
||||
climate::ClimateTraits traits() override;
|
||||
|
||||
/// Transmit via IR the state of this climate controller.
|
||||
void transmit_state_();
|
||||
|
||||
bool on_receive(RemoteReceiveData data) override;
|
||||
|
||||
bool supports_cool_;
|
||||
bool supports_heat_;
|
||||
|
||||
remote_transmitter::RemoteTransmitterComponent *transmitter_;
|
||||
sensor::Sensor *sensor_{nullptr};
|
||||
void transmit_state() override;
|
||||
/// Handle received IR Buffer
|
||||
bool on_receive(remote_base::RemoteReceiveData data) override;
|
||||
};
|
||||
|
||||
} // namespace coolix
|
||||
|
|
Loading…
Reference in a new issue