Add AEHA IR Protocol (#3726)

This commit is contained in:
yuhei mukoyama 2022-08-31 13:43:33 +09:00 committed by GitHub
parent 15eb9605a8
commit 0907de8662
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 197 additions and 0 deletions

View file

@ -1338,3 +1338,48 @@ def midea_dumper(var, config):
)
async def midea_action(var, config, args):
cg.add(var.set_code(config[CONF_CODE]))
# AEHA
AEHAData, AEHABinarySensor, AEHATrigger, AEHAAction, AEHADumper = declare_protocol(
"AEHA"
)
AEHA_SCHEMA = cv.Schema(
{
cv.Required(CONF_ADDRESS): cv.hex_uint16_t,
cv.Required(CONF_DATA): cv.All(
[cv.Any(cv.hex_uint8_t, cv.uint8_t)],
cv.Length(min=2, max=35),
),
}
)
@register_binary_sensor("aeha", AEHABinarySensor, AEHA_SCHEMA)
def aeha_binary_sensor(var, config):
cg.add(
var.set_data(
cg.StructInitializer(
AEHAData,
("address", config[CONF_ADDRESS]),
("data", config[CONF_DATA]),
)
)
)
@register_trigger("aeha", AEHATrigger, AEHAData)
def aeha_trigger(var, config):
pass
@register_dumper("aeha", AEHADumper)
def aeha_dumper(var, config):
pass
@register_action("aeha", AEHAAction, AEHA_SCHEMA)
async def aeha_action(var, config, args):
template_ = await cg.templatable(config[CONF_ADDRESS], args, cg.uint16)
cg.add(var.set_address(template_))
cg.add(var.set_data(config[CONF_DATA]))

View file

@ -0,0 +1,103 @@
#include "aeha_protocol.h"
#include "esphome/core/log.h"
#include <cinttypes>
namespace esphome {
namespace remote_base {
static const char *const TAG = "remote.aeha";
static const uint16_t BITWISE = 425;
static const uint16_t HEADER_HIGH_US = BITWISE * 8;
static const uint16_t HEADER_LOW_US = BITWISE * 4;
static const uint16_t BIT_HIGH_US = BITWISE;
static const uint16_t BIT_ONE_LOW_US = BITWISE * 3;
static const uint16_t BIT_ZERO_LOW_US = BITWISE;
static const uint16_t TRAILER = BITWISE;
void AEHAProtocol::encode(RemoteTransmitData *dst, const AEHAData &data) {
dst->set_carrier_frequency(38000);
dst->reserve(2 + 32 + (data.data.size() * 2) + 1);
dst->item(HEADER_HIGH_US, HEADER_LOW_US);
for (uint16_t mask = 1 << 15; mask != 0; mask >>= 1) {
if (data.address & mask) {
dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
} else {
dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
}
}
for (uint8_t bit : data.data) {
for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) {
if (bit & mask) {
dst->item(BIT_HIGH_US, BIT_ONE_LOW_US);
} else {
dst->item(BIT_HIGH_US, BIT_ZERO_LOW_US);
}
}
}
dst->mark(TRAILER);
}
optional<AEHAData> AEHAProtocol::decode(RemoteReceiveData src) {
AEHAData out{
.address = 0,
.data = {},
};
if (!src.expect_item(HEADER_HIGH_US, HEADER_LOW_US))
return {};
for (uint16_t mask = 1 << 15; mask != 0; mask >>= 1) {
if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
out.address |= mask;
} else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
out.address &= ~mask;
} else {
return {};
}
}
for (uint8_t pos = 0; pos < 35; pos++) {
uint8_t data = 0;
for (uint8_t mask = 1 << 7; mask != 0; mask >>= 1) {
if (src.expect_item(BIT_HIGH_US, BIT_ONE_LOW_US)) {
data |= mask;
} else if (src.expect_item(BIT_HIGH_US, BIT_ZERO_LOW_US)) {
data &= ~mask;
} else if (pos > 1 && src.expect_mark(TRAILER)) {
return out;
} else {
return {};
}
}
out.data.push_back(data);
}
if (src.expect_mark(TRAILER)) {
return out;
}
return {};
}
std::string AEHAProtocol::format_data_(const std::vector<uint8_t> &data) {
std::string out;
for (uint8_t byte : data) {
char buf[6];
sprintf(buf, "0x%02X,", byte);
out += buf;
}
out.pop_back();
return out;
}
void AEHAProtocol::dump(const AEHAData &data) {
auto data_str = format_data_(data.data);
ESP_LOGD(TAG, "Received AEHA: address=0x%04X, data=[%s]", data.address, data_str.c_str());
}
} // namespace remote_base
} // namespace esphome

View file

@ -0,0 +1,42 @@
#pragma once
#include "remote_base.h"
namespace esphome {
namespace remote_base {
struct AEHAData {
uint16_t address;
std::vector<uint8_t> data;
bool operator==(const AEHAData &rhs) const { return address == rhs.address && data == rhs.data; }
};
class AEHAProtocol : public RemoteProtocol<AEHAData> {
public:
void encode(RemoteTransmitData *dst, const AEHAData &data) override;
optional<AEHAData> decode(RemoteReceiveData src) override;
void dump(const AEHAData &data) override;
private:
std::string format_data_(const std::vector<uint8_t> &data);
};
DECLARE_REMOTE_PROTOCOL(AEHA)
template<typename... Ts> class AEHAAction : public RemoteTransmitterActionBase<Ts...> {
public:
TEMPLATABLE_VALUE(uint16_t, address)
TEMPLATABLE_VALUE(std::vector<uint8_t>, data)
void set_data(const std::vector<uint8_t> &data) { data_ = data; }
void encode(RemoteTransmitData *dst, Ts... x) override {
AEHAData data{};
data.address = this->address_.value(x...);
data.data = this->data_.value(x...);
AEHAProtocol().encode(dst, data);
}
};
} // namespace remote_base
} // namespace esphome

View file

@ -2085,6 +2085,13 @@ switch:
turn_on_action:
remote_transmitter.transmit_raw:
code: [1000, -1000]
- platform: template
name: AEHA
id: eaha_hitachi_climate_power_on
turn_on_action:
remote_transmitter.transmit_aeha:
address: 0x8008
data: [0x00, 0x02, 0xFD, 0xFF, 0x00, 0x33, 0xCC, 0x49, 0xB6, 0xC8, 0x37, 0x16, 0xE9, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xCA, 0x35, 0x8F, 0x70, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF]
- platform: template
name: Living Room Lights
id: livingroom_lights