mirror of
https://github.com/esphome/esphome.git
synced 2025-01-18 12:05:41 +00:00
Emmeti infrared climate support (#5197)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
3abf2f1d14
commit
b34b10888b
@ -103,6 +103,7 @@ esphome/components/duty_time/* @dudanov
|
|||||||
esphome/components/ee895/* @Stock-M
|
esphome/components/ee895/* @Stock-M
|
||||||
esphome/components/ektf2232/touchscreen/* @jesserockz
|
esphome/components/ektf2232/touchscreen/* @jesserockz
|
||||||
esphome/components/emc2101/* @ellull
|
esphome/components/emc2101/* @ellull
|
||||||
|
esphome/components/emmeti/* @E440QF
|
||||||
esphome/components/ens160/* @vincentscode
|
esphome/components/ens160/* @vincentscode
|
||||||
esphome/components/ens210/* @itn3rd77
|
esphome/components/ens210/* @itn3rd77
|
||||||
esphome/components/esp32/* @esphome/core
|
esphome/components/esp32/* @esphome/core
|
||||||
|
0
esphome/components/emmeti/__init__.py
Normal file
0
esphome/components/emmeti/__init__.py
Normal file
21
esphome/components/emmeti/climate.py
Normal file
21
esphome/components/emmeti/climate.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import climate_ir
|
||||||
|
from esphome.const import CONF_ID
|
||||||
|
|
||||||
|
CODEOWNERS = ["@E440QF"]
|
||||||
|
AUTO_LOAD = ["climate_ir"]
|
||||||
|
|
||||||
|
emmeti_ns = cg.esphome_ns.namespace("emmeti")
|
||||||
|
EmmetiClimate = emmeti_ns.class_("EmmetiClimate", climate_ir.ClimateIR)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(EmmetiClimate),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await climate_ir.register_climate_ir(var, config)
|
316
esphome/components/emmeti/emmeti.cpp
Normal file
316
esphome/components/emmeti/emmeti.cpp
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
#include "emmeti.h"
|
||||||
|
#include "esphome/components/remote_base/remote_base.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace emmeti {
|
||||||
|
|
||||||
|
static const char *const TAG = "emmeti.climate";
|
||||||
|
|
||||||
|
// setters
|
||||||
|
uint8_t EmmetiClimate::set_temp_() {
|
||||||
|
return (uint8_t) roundf(clamp<float>(this->target_temperature, EMMETI_TEMP_MIN, EMMETI_TEMP_MAX) - EMMETI_TEMP_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t EmmetiClimate::set_mode_() {
|
||||||
|
switch (this->mode) {
|
||||||
|
case climate::CLIMATE_MODE_COOL:
|
||||||
|
return EMMETI_MODE_COOL;
|
||||||
|
case climate::CLIMATE_MODE_DRY:
|
||||||
|
return EMMETI_MODE_DRY;
|
||||||
|
case climate::CLIMATE_MODE_HEAT:
|
||||||
|
return EMMETI_MODE_HEAT;
|
||||||
|
case climate::CLIMATE_MODE_FAN_ONLY:
|
||||||
|
return EMMETI_MODE_FAN;
|
||||||
|
case climate::CLIMATE_MODE_HEAT_COOL:
|
||||||
|
default:
|
||||||
|
return EMMETI_MODE_HEAT_COOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t EmmetiClimate::set_fan_speed_() {
|
||||||
|
switch (this->fan_mode.value()) {
|
||||||
|
case climate::CLIMATE_FAN_LOW:
|
||||||
|
return EMMETI_FAN_1;
|
||||||
|
case climate::CLIMATE_FAN_MEDIUM:
|
||||||
|
return EMMETI_FAN_2;
|
||||||
|
case climate::CLIMATE_FAN_HIGH:
|
||||||
|
return EMMETI_FAN_3;
|
||||||
|
case climate::CLIMATE_FAN_AUTO:
|
||||||
|
default:
|
||||||
|
return EMMETI_FAN_AUTO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t EmmetiClimate::set_blades_() {
|
||||||
|
if (this->swing_mode == climate::CLIMATE_SWING_VERTICAL) {
|
||||||
|
switch (this->blades_) {
|
||||||
|
case EMMETI_BLADES_1:
|
||||||
|
case EMMETI_BLADES_2:
|
||||||
|
case EMMETI_BLADES_HIGH:
|
||||||
|
this->blades_ = EMMETI_BLADES_HIGH;
|
||||||
|
break;
|
||||||
|
case EMMETI_BLADES_3:
|
||||||
|
case EMMETI_BLADES_MID:
|
||||||
|
this->blades_ = EMMETI_BLADES_MID;
|
||||||
|
break;
|
||||||
|
case EMMETI_BLADES_4:
|
||||||
|
case EMMETI_BLADES_5:
|
||||||
|
case EMMETI_BLADES_LOW:
|
||||||
|
this->blades_ = EMMETI_BLADES_LOW;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this->blades_ = EMMETI_BLADES_FULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (this->blades_) {
|
||||||
|
case EMMETI_BLADES_1:
|
||||||
|
case EMMETI_BLADES_2:
|
||||||
|
case EMMETI_BLADES_HIGH:
|
||||||
|
this->blades_ = EMMETI_BLADES_1;
|
||||||
|
break;
|
||||||
|
case EMMETI_BLADES_3:
|
||||||
|
case EMMETI_BLADES_MID:
|
||||||
|
this->blades_ = EMMETI_BLADES_3;
|
||||||
|
break;
|
||||||
|
case EMMETI_BLADES_4:
|
||||||
|
case EMMETI_BLADES_5:
|
||||||
|
case EMMETI_BLADES_LOW:
|
||||||
|
this->blades_ = EMMETI_BLADES_5;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this->blades_ = EMMETI_BLADES_STOP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this->blades_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t EmmetiClimate::gen_checksum_() { return (this->set_temp_() + this->set_mode_() + 2) % 16; }
|
||||||
|
|
||||||
|
// getters
|
||||||
|
float EmmetiClimate::get_temp_(uint8_t temp) { return (float) (temp + EMMETI_TEMP_MIN); }
|
||||||
|
|
||||||
|
climate::ClimateMode EmmetiClimate::get_mode_(uint8_t mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case EMMETI_MODE_COOL:
|
||||||
|
return climate::CLIMATE_MODE_COOL;
|
||||||
|
case EMMETI_MODE_DRY:
|
||||||
|
return climate::CLIMATE_MODE_DRY;
|
||||||
|
case EMMETI_MODE_HEAT:
|
||||||
|
return climate::CLIMATE_MODE_HEAT;
|
||||||
|
case EMMETI_MODE_HEAT_COOL:
|
||||||
|
return climate::CLIMATE_MODE_HEAT_COOL;
|
||||||
|
case EMMETI_MODE_FAN:
|
||||||
|
return climate::CLIMATE_MODE_FAN_ONLY;
|
||||||
|
default:
|
||||||
|
return climate::CLIMATE_MODE_HEAT_COOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
climate::ClimateFanMode EmmetiClimate::get_fan_speed_(uint8_t fan_speed) {
|
||||||
|
switch (fan_speed) {
|
||||||
|
case EMMETI_FAN_1:
|
||||||
|
return climate::CLIMATE_FAN_LOW;
|
||||||
|
case EMMETI_FAN_2:
|
||||||
|
return climate::CLIMATE_FAN_MEDIUM;
|
||||||
|
case EMMETI_FAN_3:
|
||||||
|
return climate::CLIMATE_FAN_HIGH;
|
||||||
|
case EMMETI_FAN_AUTO:
|
||||||
|
default:
|
||||||
|
return climate::CLIMATE_FAN_AUTO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
climate::ClimateSwingMode EmmetiClimate::get_swing_(uint8_t bitmap) {
|
||||||
|
return (bitmap >> 1) & 0x01 ? climate::CLIMATE_SWING_VERTICAL : climate::CLIMATE_SWING_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> T EmmetiClimate::reverse_(T val, size_t len) {
|
||||||
|
T result = 0;
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
result |= ((val & 1 << i) != 0) << (len - 1 - i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void EmmetiClimate::add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *data) {
|
||||||
|
for (size_t i = len; i > 0; i--) {
|
||||||
|
data->mark(EMMETI_BIT_MARK);
|
||||||
|
data->space((val & (1 << (i - 1))) ? EMMETI_ONE_SPACE : EMMETI_ZERO_SPACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void EmmetiClimate::add_(T val, esphome::remote_base::RemoteTransmitData *data) {
|
||||||
|
data->mark(EMMETI_BIT_MARK);
|
||||||
|
data->space((val & 1) ? EMMETI_ONE_SPACE : EMMETI_ZERO_SPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void EmmetiClimate::reverse_add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *data) {
|
||||||
|
this->add_(this->reverse_(val, len), len, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmmetiClimate::check_checksum_(uint8_t checksum) {
|
||||||
|
uint8_t expected = this->gen_checksum_();
|
||||||
|
ESP_LOGV(TAG, "Expected checksum: %X", expected);
|
||||||
|
ESP_LOGV(TAG, "Checksum received: %X", checksum);
|
||||||
|
|
||||||
|
return checksum == expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmmetiClimate::transmit_state() {
|
||||||
|
auto transmit = this->transmitter_->transmit();
|
||||||
|
auto *data = transmit.get_data();
|
||||||
|
data->set_carrier_frequency(EMMETI_IR_FREQUENCY);
|
||||||
|
|
||||||
|
data->mark(EMMETI_HEADER_MARK);
|
||||||
|
data->space(EMMETI_HEADER_SPACE);
|
||||||
|
|
||||||
|
if (this->mode != climate::CLIMATE_MODE_OFF) {
|
||||||
|
this->reverse_add_(this->set_mode_(), 3, data);
|
||||||
|
this->add_(1, data);
|
||||||
|
this->reverse_add_(this->set_fan_speed_(), 2, data);
|
||||||
|
this->add_(this->swing_mode != climate::CLIMATE_SWING_OFF, data);
|
||||||
|
this->add_(0, data); // sleep mode
|
||||||
|
this->reverse_add_(this->set_temp_(), 4, data);
|
||||||
|
this->add_(0, 8, data); // zeros
|
||||||
|
this->add_(0, data); // turbo mode
|
||||||
|
this->add_(1, data); // light
|
||||||
|
this->add_(1, data); // tree icon thingy
|
||||||
|
this->add_(0, data); // blow mode
|
||||||
|
this->add_(0x52, 11, data); // idk
|
||||||
|
|
||||||
|
data->mark(EMMETI_BIT_MARK);
|
||||||
|
data->space(EMMETI_MESSAGE_SPACE);
|
||||||
|
|
||||||
|
this->reverse_add_(this->set_blades_(), 4, data);
|
||||||
|
this->add_(0, 4, data); // zeros
|
||||||
|
this->reverse_add_(2, 2, data); // thermometer
|
||||||
|
this->add_(0, 18, data); // zeros
|
||||||
|
this->reverse_add_(this->gen_checksum_(), 4, data);
|
||||||
|
} else {
|
||||||
|
this->add_(9, 12, data);
|
||||||
|
this->add_(0, 8, data);
|
||||||
|
this->add_(0x2052, 15, data);
|
||||||
|
data->mark(EMMETI_BIT_MARK);
|
||||||
|
data->space(EMMETI_MESSAGE_SPACE);
|
||||||
|
this->add_(0, 8, data);
|
||||||
|
this->add_(1, 2, data);
|
||||||
|
this->add_(0, 18, data);
|
||||||
|
this->add_(0x0C, 4, data);
|
||||||
|
}
|
||||||
|
data->mark(EMMETI_BIT_MARK);
|
||||||
|
data->space(0);
|
||||||
|
|
||||||
|
transmit.perform();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmmetiClimate::parse_state_frame_(EmmetiState curr_state) {
|
||||||
|
this->mode = this->get_mode_(curr_state.mode);
|
||||||
|
this->fan_mode = this->get_fan_speed_(curr_state.fan_speed);
|
||||||
|
this->target_temperature = this->get_temp_(curr_state.temp);
|
||||||
|
this->swing_mode = this->get_swing_(curr_state.bitmap);
|
||||||
|
// this->blades_ = curr_state.fan_pos;
|
||||||
|
if (!(curr_state.bitmap & 0x01)) {
|
||||||
|
this->mode = climate::CLIMATE_MODE_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->publish_state();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmmetiClimate::on_receive(remote_base::RemoteReceiveData data) {
|
||||||
|
if (!data.expect_item(EMMETI_HEADER_MARK, EMMETI_HEADER_SPACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "Received emmeti frame");
|
||||||
|
|
||||||
|
EmmetiState curr_state;
|
||||||
|
|
||||||
|
for (size_t pos = 0; pos < 3; pos++) {
|
||||||
|
if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) {
|
||||||
|
curr_state.mode |= 1 << pos;
|
||||||
|
} else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Mode: %d", curr_state.mode);
|
||||||
|
|
||||||
|
if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) {
|
||||||
|
curr_state.bitmap |= 1 << 0;
|
||||||
|
} else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "On: %d", curr_state.bitmap & 0x01);
|
||||||
|
|
||||||
|
for (size_t pos = 0; pos < 2; pos++) {
|
||||||
|
if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) {
|
||||||
|
curr_state.fan_speed |= 1 << pos;
|
||||||
|
} else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Fan speed: %d", curr_state.fan_speed);
|
||||||
|
|
||||||
|
for (size_t pos = 0; pos < 2; pos++) {
|
||||||
|
if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) {
|
||||||
|
curr_state.bitmap |= 1 << (pos + 1);
|
||||||
|
} else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Swing: %d", (curr_state.bitmap >> 1) & 0x01);
|
||||||
|
ESP_LOGD(TAG, "Sleep: %d", (curr_state.bitmap >> 2) & 0x01);
|
||||||
|
|
||||||
|
for (size_t pos = 0; pos < 4; pos++) {
|
||||||
|
if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) {
|
||||||
|
curr_state.temp |= 1 << pos;
|
||||||
|
} else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Temp: %d", curr_state.temp);
|
||||||
|
|
||||||
|
for (size_t pos = 0; pos < 8; pos++) {
|
||||||
|
if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t pos = 0; pos < 4; pos++) {
|
||||||
|
if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) {
|
||||||
|
curr_state.bitmap |= 1 << (pos + 3);
|
||||||
|
} else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "Turbo: %d", (curr_state.bitmap >> 3) & 0x01);
|
||||||
|
ESP_LOGD(TAG, "Light: %d", (curr_state.bitmap >> 4) & 0x01);
|
||||||
|
ESP_LOGD(TAG, "Tree: %d", (curr_state.bitmap >> 5) & 0x01);
|
||||||
|
ESP_LOGD(TAG, "Blow: %d", (curr_state.bitmap >> 6) & 0x01);
|
||||||
|
|
||||||
|
uint16_t control_data = 0;
|
||||||
|
for (size_t pos = 0; pos < 11; pos++) {
|
||||||
|
if (data.expect_item(EMMETI_BIT_MARK, EMMETI_ONE_SPACE)) {
|
||||||
|
control_data |= 1 << pos;
|
||||||
|
} else if (!data.expect_item(EMMETI_BIT_MARK, EMMETI_ZERO_SPACE)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (control_data != 0x250) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->parse_state_frame_(curr_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace emmeti
|
||||||
|
} // namespace esphome
|
109
esphome/components/emmeti/emmeti.h
Normal file
109
esphome/components/emmeti/emmeti.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/climate_ir/climate_ir.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace emmeti {
|
||||||
|
|
||||||
|
const uint8_t EMMETI_TEMP_MIN = 16; // Celsius
|
||||||
|
const uint8_t EMMETI_TEMP_MAX = 30; // Celsius
|
||||||
|
|
||||||
|
// Modes
|
||||||
|
|
||||||
|
enum EmmetiMode : uint8_t {
|
||||||
|
EMMETI_MODE_HEAT_COOL = 0x00,
|
||||||
|
EMMETI_MODE_COOL = 0x01,
|
||||||
|
EMMETI_MODE_DRY = 0x02,
|
||||||
|
EMMETI_MODE_FAN = 0x03,
|
||||||
|
EMMETI_MODE_HEAT = 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fan Speed
|
||||||
|
|
||||||
|
enum EmmetiFanMode : uint8_t {
|
||||||
|
EMMETI_FAN_AUTO = 0x00,
|
||||||
|
EMMETI_FAN_1 = 0x01,
|
||||||
|
EMMETI_FAN_2 = 0x02,
|
||||||
|
EMMETI_FAN_3 = 0x03,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Fan Position
|
||||||
|
|
||||||
|
enum EmmetiBlades : uint8_t {
|
||||||
|
EMMETI_BLADES_STOP = 0x00,
|
||||||
|
EMMETI_BLADES_FULL = 0x01,
|
||||||
|
EMMETI_BLADES_1 = 0x02,
|
||||||
|
EMMETI_BLADES_2 = 0x03,
|
||||||
|
EMMETI_BLADES_3 = 0x04,
|
||||||
|
EMMETI_BLADES_4 = 0x05,
|
||||||
|
EMMETI_BLADES_5 = 0x06,
|
||||||
|
EMMETI_BLADES_LOW = 0x07,
|
||||||
|
EMMETI_BLADES_MID = 0x09,
|
||||||
|
EMMETI_BLADES_HIGH = 0x11,
|
||||||
|
};
|
||||||
|
|
||||||
|
// IR Transmission
|
||||||
|
const uint32_t EMMETI_IR_FREQUENCY = 38000;
|
||||||
|
const uint32_t EMMETI_HEADER_MARK = 9076;
|
||||||
|
const uint32_t EMMETI_HEADER_SPACE = 4408;
|
||||||
|
const uint32_t EMMETI_BIT_MARK = 660;
|
||||||
|
const uint32_t EMMETI_ONE_SPACE = 1630;
|
||||||
|
const uint32_t EMMETI_ZERO_SPACE = 530;
|
||||||
|
const uint32_t EMMETI_MESSAGE_SPACE = 20000;
|
||||||
|
|
||||||
|
struct EmmetiState {
|
||||||
|
uint8_t mode = 0;
|
||||||
|
uint8_t bitmap = 0;
|
||||||
|
uint8_t fan_speed = 0;
|
||||||
|
uint8_t temp = 0;
|
||||||
|
uint8_t fan_pos = 0;
|
||||||
|
uint8_t th = 0;
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EmmetiClimate : public climate_ir::ClimateIR {
|
||||||
|
public:
|
||||||
|
EmmetiClimate()
|
||||||
|
: climate_ir::ClimateIR(EMMETI_TEMP_MIN, EMMETI_TEMP_MAX, 1.0f, true, true,
|
||||||
|
{climate::CLIMATE_FAN_AUTO, climate::CLIMATE_FAN_LOW, climate::CLIMATE_FAN_MEDIUM,
|
||||||
|
climate::CLIMATE_FAN_HIGH},
|
||||||
|
{climate::CLIMATE_SWING_OFF, climate::CLIMATE_SWING_VERTICAL}) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Transmit via IR the state of this climate controller
|
||||||
|
void transmit_state() override;
|
||||||
|
// Handle received IR Buffer
|
||||||
|
bool on_receive(remote_base::RemoteReceiveData data) override;
|
||||||
|
bool parse_state_frame_(EmmetiState curr_state);
|
||||||
|
|
||||||
|
// setters
|
||||||
|
uint8_t set_mode_();
|
||||||
|
uint8_t set_temp_();
|
||||||
|
uint8_t set_fan_speed_();
|
||||||
|
uint8_t gen_checksum_();
|
||||||
|
uint8_t set_blades_();
|
||||||
|
|
||||||
|
// getters
|
||||||
|
climate::ClimateMode get_mode_(uint8_t mode);
|
||||||
|
climate::ClimateFanMode get_fan_speed_(uint8_t fan);
|
||||||
|
void get_blades_(uint8_t fanpos);
|
||||||
|
// get swing
|
||||||
|
climate::ClimateSwingMode get_swing_(uint8_t bitmap);
|
||||||
|
float get_temp_(uint8_t temp);
|
||||||
|
|
||||||
|
// check if the received frame is valid
|
||||||
|
bool check_checksum_(uint8_t checksum);
|
||||||
|
|
||||||
|
template<typename T> T reverse_(T val, size_t len);
|
||||||
|
|
||||||
|
template<typename T> void add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *ata);
|
||||||
|
|
||||||
|
template<typename T> void add_(T val, esphome::remote_base::RemoteTransmitData *data);
|
||||||
|
|
||||||
|
template<typename T> void reverse_add_(T val, size_t len, esphome::remote_base::RemoteTransmitData *data);
|
||||||
|
|
||||||
|
uint8_t blades_ = EMMETI_BLADES_STOP;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace emmeti
|
||||||
|
} // namespace esphome
|
14
tests/components/emmeti/common.yaml
Normal file
14
tests/components/emmeti/common.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
remote_transmitter:
|
||||||
|
id: tx
|
||||||
|
pin: ${remote_transmitter_pin}
|
||||||
|
carrier_duty_percent: 100%
|
||||||
|
|
||||||
|
remote_receiver:
|
||||||
|
id: rcvr
|
||||||
|
pin: ${remote_receiver_pin}
|
||||||
|
|
||||||
|
climate:
|
||||||
|
- platform: emmeti
|
||||||
|
name: Emmeti
|
||||||
|
receiver_id: rcvr
|
||||||
|
transmitter_id: tx
|
5
tests/components/emmeti/test.esp32-idf.yaml
Normal file
5
tests/components/emmeti/test.esp32-idf.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
substitutions:
|
||||||
|
remote_transmitter_pin: GPIO33
|
||||||
|
remote_receiver_pin: GPIO32
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/emmeti/test.esp32.yaml
Normal file
5
tests/components/emmeti/test.esp32.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
substitutions:
|
||||||
|
remote_transmitter_pin: GPIO33
|
||||||
|
remote_receiver_pin: GPIO32
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
5
tests/components/emmeti/test.esp8266.yaml
Normal file
5
tests/components/emmeti/test.esp8266.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
substitutions:
|
||||||
|
remote_transmitter_pin: GPIO4
|
||||||
|
remote_receiver_pin: GPIO5
|
||||||
|
|
||||||
|
<<: !include common.yaml
|
Loading…
x
Reference in New Issue
Block a user