ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
aok_protocol.cpp
Go to the documentation of this file.
1#include "aok_protocol.h"
2#include "esphome/core/log.h"
3
4namespace esphome::remote_base {
5
6ESPHOME_LOG_TAG(TAG, "remote.aok");
7
8// A frame is a long start mark, then 64 bits, then a long gap. A one bit is a long mark and a short space,
9// a zero bit is a short mark and a long space. The bits are: header (8), remote id (24), channels (16),
10// command (8) and checksum (8), most significant bit first.
11static constexpr uint8_t NBITS = 64;
12static constexpr uint32_t START_HIGH_US = 5000;
13static constexpr uint32_t LONG_US = 600;
14static constexpr uint32_t SHORT_US = 285;
15static constexpr uint8_t HEADER = 0xA3;
16static constexpr uint32_t REMOTE_ID_MASK = 0xFFFFFF;
17
18// The sum of the six bytes between the header and the checksum
19static uint8_t checksum(uint64_t frame) {
20 uint8_t sum = 0;
21 for (uint8_t shift = 8; shift < 56; shift += 8) {
22 sum += frame >> shift;
23 }
24 return sum;
25}
26
28 uint64_t frame = (uint64_t(HEADER) << 56) | (uint64_t(data.remote_id & REMOTE_ID_MASK) << 32) |
29 (uint64_t(data.channels) << 16) | (uint64_t(data.command) << 8);
30 frame |= checksum(frame);
31
32 dst->reserve((NBITS + 2) * 2);
33 dst->item(START_HIGH_US, LONG_US);
34 for (uint64_t mask = 1ULL << (NBITS - 1); mask; mask >>= 1) {
35 if (frame & mask) {
36 dst->item(LONG_US, SHORT_US);
37 } else {
38 dst->item(SHORT_US, LONG_US);
39 }
40 }
41 dst->item(LONG_US, START_HIGH_US);
42}
43
45 // A buffer can hold noise and several repeats of a frame, so look for the first good one. After any
46 // failure the loop restarts at the next timing, or where the failed frame stopped.
47 while (src.is_valid()) {
48 if (!src.expect_pulse_with_gap(START_HIGH_US, LONG_US)) {
49 src.advance();
50 continue;
51 }
52
53 uint64_t frame = 0;
54 uint8_t bits = 0;
55 for (; bits < NBITS; bits++) {
56 frame <<= 1;
57 if (src.expect_item(LONG_US, SHORT_US)) {
58 frame |= 1;
59 } else if (!src.expect_item(SHORT_US, LONG_US)) {
60 break;
61 }
62 }
63
64 if (bits == NBITS && uint8_t(frame >> 56) == HEADER && uint8_t(frame) == checksum(frame)) {
65 return AOKData{
66 .remote_id = uint32_t(frame >> 32) & REMOTE_ID_MASK,
67 .channels = uint16_t(frame >> 16),
68 .command = uint8_t(frame >> 8),
69 };
70 }
71 }
72 return {};
73}
74
75void AOKProtocol::dump(const AOKData &data) {
76 ESP_LOGI(TAG, "Received A-OK: remote_id=0x%06" PRIX32 ", channels=0x%04X, command=0x%02X", data.remote_id,
77 data.channels, data.command);
78}
79
80} // namespace esphome::remote_base
uint8_t checksum
Definition bl0906.h:3
optional< AOKData > decode(RemoteReceiveData src)
void encode(RemoteTransmitData *dst, const AOKData &data)
void dump(const AOKData &data)
void item(uint32_t mark, uint32_t space)
Definition remote_base.h:43
ESPHOME_LOG_TAG(TAG, "remote.abbwelcome")
const void * src
Definition hal.h:68
static void uint32_t