Skip to content

Commit

Permalink
Support for short Panasonic A/C messages. (#553)
Browse files Browse the repository at this point in the history
* Support for short Panasonic A/C messages.
Panasonic A/C messages have a 16 byte/128 bit short state for
some special IR remote messages.
* Only report text for full panasonic A/C messages.

Ref: #540 & #544
  • Loading branch information
crankyoldgit authored Oct 14, 2018
1 parent 9aaa511 commit ae3280f
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 5 deletions.
3 changes: 2 additions & 1 deletion examples/IRrecvDumpV2/IRrecvDumpV2.ino
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ void dumpACInfo(decode_results *results) {
}
#endif // DECODE_COOLIX
#if DECODE_PANASONIC_AC
if (results->decode_type == PANASONIC_AC) {
if (results->decode_type == PANASONIC_AC &&
results->bits > kPanasonicAcShortBits) {
IRPanasonicAc ac(0);
ac.setRaw(results->state);
description = ac.toString();
Expand Down
3 changes: 3 additions & 0 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,9 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) {
DPRINTLN("Attempting Panasonic AC decode");
if (decodePanasonicAC(results))
return true;
DPRINTLN("Attempting Panasonic AC short decode");
if (decodePanasonicAC(results, kPanasonicAcShortBits))
return true;
#endif
#if DECODE_LUTRON
DPRINTLN("Attempting Lutron decode");
Expand Down
2 changes: 2 additions & 0 deletions src/IRremoteESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,9 @@ const uint16_t kNECBits = 32;
const uint16_t kPanasonicBits = 48;
const uint32_t kPanasonicManufacturer = 0x4004;
const uint16_t kPanasonicAcStateLength = 27;
const uint16_t kPanasonicAcStateShortLength = 16;
const uint16_t kPanasonicAcBits = kPanasonicAcStateLength * 8;
const uint16_t kPanasonicAcShortBits = kPanasonicAcStateShortLength * 8;
const uint16_t kProntoMinLength = 6;
const uint16_t kRC5RawBits = 14;
const uint16_t kRC5Bits = kRC5RawBits - 2;
Expand Down
4 changes: 2 additions & 2 deletions src/ir_Panasonic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ bool IRrecv::decodePanasonic(decode_results *results, uint16_t nbits,
// A75C3704
//
void IRsend::sendPanasonicAC(uint8_t data[], uint16_t nbytes, uint16_t repeat) {
if (nbytes < kPanasonicAcStateLength) return;
if (nbytes < kPanasonicAcSection1Length) return;
for (uint16_t r = 0; r <= repeat; r++) {
// First section. (8 bytes)
sendGeneric(kPanasonicHdrMark, kPanasonicHdrSpace,
Expand Down Expand Up @@ -754,7 +754,7 @@ bool IRrecv::decodePanasonicAC(decode_results *results, uint16_t nbits,

uint8_t min_nr_of_messages = 1;
if (strict) {
if (nbits != kPanasonicAcBits)
if (nbits != kPanasonicAcBits && nbits != kPanasonicAcShortBits)
return false; // Not strictly a PANASONIC_AC message.
}

Expand Down
4 changes: 2 additions & 2 deletions src/ir_Panasonic.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ class IRPanasonicAc {
private:
#endif
uint8_t remote_state[kPanasonicAcStateLength];
uint8_t _swingh = kPanasonicAcSwingHMiddle;
uint8_t _temp = 25;
uint8_t _swingh;
uint8_t _temp;
void fixChecksum(const uint16_t length = kPanasonicAcStateLength);
static uint8_t calcChecksum(const uint8_t *state,
const uint16_t length = kPanasonicAcStateLength);
Expand Down
60 changes: 60 additions & 0 deletions test/ir_Panasonic_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,3 +984,63 @@ TEST(TestIRPanasonicAcClass, TimersAndClock) {
pana.setClock(kPanasonicAcTimeSpecial);
EXPECT_EQ(0, pana.getClock());
}

// Decode a real short Panasonic AC message
TEST(TestDecodePanasonicAC, RealExampleOfShortMessage) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();

// Data from Issue #544 (Odour Wash)
uint16_t rawData[263] = {3496, 1734, 506, 366, 448, 1294, 504, 368, 498, 374,
452, 418, 448, 424, 444, 428, 450, 422, 446, 426, 450, 420, 448, 424,
452, 418, 448, 422, 444, 1300, 498, 374, 504, 368, 448, 424, 452, 418,
448, 424, 444, 428, 450, 422, 446, 1296, 500, 1242, 502, 1242, 504, 368,
498, 374, 452, 1292, 504, 366, 450, 422, 444, 426, 450, 420, 446, 424,
452, 418, 448, 424, 444, 428, 450, 422, 444, 426, 450, 420, 446, 424,
452, 418, 448, 422, 444, 428, 450, 422, 446, 426, 452, 420, 446, 426,
452, 418, 448, 424, 442, 428, 448, 422, 444, 426, 450, 420, 446, 426,
452, 418, 448, 424, 444, 428, 450, 422, 444, 1298, 500, 1244, 500, 372,
444, 428, 450, 422, 446, 426, 452, 418, 448, 10020, 3500, 1732, 498, 372,
452, 1290, 506, 366, 450, 422, 446, 426, 452, 420, 448, 424, 452, 418,
448, 422, 444, 426, 450, 420, 446, 426, 452, 420, 446, 1296, 500, 370,
444, 428, 450, 422, 446, 426, 452, 420, 446, 424, 442, 428, 448, 1294,
502, 1240, 504, 1238, 506, 366, 448, 422, 444, 1298, 498, 374, 452, 418,
448, 424, 444, 428, 450, 422, 446, 426, 450, 420, 446, 424, 452, 418,
448, 422, 444, 428, 450, 420, 446, 1298, 498, 1244, 500, 1242, 502, 368,
446, 1298, 500, 1244, 500, 372, 444, 428, 450, 1292, 504, 368, 446, 1296,
502, 370, 444, 426, 452, 1290, 504, 1238, 506, 366, 450, 422, 446, 1298,
498, 1246, 500, 372, 444, 428, 450, 1294, 452, 420, 446, 1296, 448, 422,
444}; // UNKNOWN 1FB51F79

uint8_t expectedState[kPanasonicAcStateShortLength] = {
0x02, 0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x06,
0x02, 0x20, 0xE0, 0x04, 0x80, 0x9B, 0x32, 0x53};

irsend.sendRaw(rawData, 263, kPanasonicFreq);
irsend.makeDecodeResult();

ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(PANASONIC_AC, irsend.capture.decode_type);
EXPECT_EQ(kPanasonicAcShortBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
}

// Create and decode a short Panasonic AC message
TEST(TestDecodePanasonicAC, SyntheticShortMessage) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();

uint8_t odourWash[kPanasonicAcStateShortLength] = {
0x02, 0x20, 0xE0, 0x04, 0x00, 0x00, 0x00, 0x06,
0x02, 0x20, 0xE0, 0x04, 0x80, 0x9B, 0x32, 0x53};

irsend.sendPanasonicAC(odourWash, kPanasonicAcStateShortLength);
irsend.makeDecodeResult();

ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(PANASONIC_AC, irsend.capture.decode_type);
EXPECT_EQ(kPanasonicAcShortBits, irsend.capture.bits);
EXPECT_STATE_EQ(odourWash, irsend.capture.state, irsend.capture.bits);
}

0 comments on commit ae3280f

Please sign in to comment.