mirror of
https://github.com/esphome/esphome.git
synced 2024-11-10 01:07:45 +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):
|
||||
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:
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue