mirror of
https://github.com/esphome/esphome.git
synced 2024-12-23 05:54:56 +01:00
Add AEHA IR Protocol (#3726)
This commit is contained in:
parent
15eb9605a8
commit
0907de8662
4 changed files with 197 additions and 0 deletions
|
@ -1338,3 +1338,48 @@ def midea_dumper(var, config):
|
||||||
)
|
)
|
||||||
async def midea_action(var, config, args):
|
async def midea_action(var, config, args):
|
||||||
cg.add(var.set_code(config[CONF_CODE]))
|
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]))
|
||||||
|
|
103
esphome/components/remote_base/aeha_protocol.cpp
Normal file
103
esphome/components/remote_base/aeha_protocol.cpp
Normal 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
|
42
esphome/components/remote_base/aeha_protocol.h
Normal file
42
esphome/components/remote_base/aeha_protocol.h
Normal 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
|
|
@ -2085,6 +2085,13 @@ switch:
|
||||||
turn_on_action:
|
turn_on_action:
|
||||||
remote_transmitter.transmit_raw:
|
remote_transmitter.transmit_raw:
|
||||||
code: [1000, -1000]
|
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
|
- platform: template
|
||||||
name: Living Room Lights
|
name: Living Room Lights
|
||||||
id: livingroom_lights
|
id: livingroom_lights
|
||||||
|
|
Loading…
Reference in a new issue