Skip to content

Commit

Permalink
Experimental support for Panasonic A/C messages. (#535)
Browse files Browse the repository at this point in the history
* Experimental support for Panasonic A/C messages.
* sendPanasonicAC(), decodePanasonicAC(), & IRPanasonicAc class added.
* Unit tests for those.
* Code HEAVILY influenced by the work done at:
  https://github.com/ToniA/ESPEasy/blob/HeatpumpIR/lib/HeatpumpIR/PanasonicHeatpumpIR.cpp
* Should support LKE/DKE/JKE/NKE series units.
* Updated example code as required.
* Panasonic AC: Improve model detect and Fan mode.
* Panasonic has a Fan mode that requires the temp to be 27C.
* Some code lint improvements.
* Detail models supported etc.
* Make the class remember the set temp, so Fan mode doesn't overwrite it.
* Adjust unit tests to cover that.
* Update unit test Makefile to include protocol header files for dependencies.

Ref: #525 (comment)

* Update sendPanasonicAC() status to confirmed.
  • Loading branch information
crankyoldgit authored Oct 2, 2018
1 parent 4fe3608 commit 17d0364
Show file tree
Hide file tree
Showing 11 changed files with 1,096 additions and 7 deletions.
9 changes: 9 additions & 0 deletions examples/IRMQTTServer/IRMQTTServer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,9 @@ bool parseStringAndSendAirCon(const uint16_t irType, const String str) {
case MITSUBISHI_AC:
stateSize = kMitsubishiACStateLength;
break;
case PANASONIC_AC:
stateSize = kPanasonicAcStateLength;
break;
case TROTEC:
stateSize = kTrotecStateLength;
break;
Expand Down Expand Up @@ -657,6 +660,11 @@ bool parseStringAndSendAirCon(const uint16_t irType, const String str) {
case ELECTRA_AC:
irsend.sendElectraAC(reinterpret_cast<uint8_t *>(state));
break;
#endif
#if SEND_PANASONIC_AC
case PANASONIC_AC:
irsend.sendPanasonicAC(reinterpret_cast<uint8_t *>(state));
break;
#endif
default:
debug("Unexpected AirCon type in send request. Not sent.");
Expand Down Expand Up @@ -1216,6 +1224,7 @@ bool sendIRCode(int const ir_type, uint64_t const code, char const * code_str,
case WHIRLPOOL_AC: // 45
case SAMSUNG_AC: // 46
case ELECTRA_AC: // 48
case PANASONIC_AC: // 49
success = parseStringAndSendAirCon(ir_type, code_str);
break;
#if SEND_DENON
Expand Down
8 changes: 8 additions & 0 deletions examples/IRrecvDumpV2/IRrecvDumpV2.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <ir_Kelvinator.h>
#include <ir_Mitsubishi.h>
#include <ir_Midea.h>
#include <ir_Panasonic.h>
#include <ir_Samsung.h>
#include <ir_Toshiba.h>

Expand Down Expand Up @@ -190,6 +191,13 @@ void dumpACInfo(decode_results *results) {
description = ac.toString();
}
#endif // DECODE_COOLIX
#if DECODE_PANASONIC_AC
if (results->decode_type == PANASONIC_AC) {
IRPanasonicAc ac(0);
ac.setRaw(results->state);
description = ac.toString();
}
#endif // DECODE_PANASONIC_AC
// If we got a human-readable description of the message, display it.
if (description != "") Serial.println("Mesg Desc.: " + description);
}
Expand Down
5 changes: 5 additions & 0 deletions src/IRrecv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,11 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) {
if (decodeElectraAC(results))
return true;
#endif
#if DECODE_PANASONIC_AC
DPRINTLN("Attempting Panasonic AC decode");
if (decodePanasonicAC(results))
return true;
#endif
#if DECODE_LUTRON
DPRINTLN("Attempting Lutron decode");
if (decodeLutron(results))
Expand Down
4 changes: 4 additions & 0 deletions src/IRrecv.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ class IRrecv {
bool decodeElectraAC(decode_results *results,
uint16_t nbits = kElectraAcBits, bool strict = true);
#endif
#if DECODE_PANASONIC_AC
bool decodePanasonicAC(decode_results *results,
uint16_t nbits = kPanasonicAcBits, bool strict = true);
#endif
};

#endif // IRRECV_H_
9 changes: 8 additions & 1 deletion src/IRremoteESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,15 @@
#define DECODE_ELECTRA_AC true
#define SEND_ELECTRA_AC true

#define DECODE_PANASONIC_AC true
#define SEND_PANASONIC_AC true

#if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \
DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \
DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \
DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || DECODE_HAIER_AC_YRW02 || \
DECODE_WHIRLPOOL_AC || DECODE_SAMSUNG_AC || DECODE_ELECTRA_AC)
DECODE_WHIRLPOOL_AC || DECODE_SAMSUNG_AC || DECODE_ELECTRA_AC || \
DECODE_PANASONIC_AC)
#define DECODE_AC true // We need some common infrastructure for decoding A/Cs.
#else
#define DECODE_AC false // We don't need that infrastructure.
Expand Down Expand Up @@ -262,6 +266,7 @@ enum decode_type_t {
SAMSUNG_AC,
LUTRON,
ELECTRA_AC,
PANASONIC_AC,
};

// Message lengths & required repeat values
Expand Down Expand Up @@ -325,6 +330,8 @@ const uint16_t kNikaiBits = 24;
const uint16_t kNECBits = 32;
const uint16_t kPanasonicBits = 48;
const uint32_t kPanasonicManufacturer = 0x4004;
const uint16_t kPanasonicAcStateLength = 27;
const uint16_t kPanasonicAcBits = kPanasonicAcStateLength * 8;
const uint16_t kProntoMinLength = 6;
const uint16_t kRC5RawBits = 14;
const uint16_t kRC5Bits = kRC5RawBits - 2;
Expand Down
5 changes: 5 additions & 0 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,11 @@ void send(uint16_t type, uint64_t data, uint16_t nbits);
uint16_t nbytes = kElectraAcStateLength,
uint16_t repeat = kNoRepeat);
#endif
#if SEND_PANASONIC_AC
void sendPanasonicAC(unsigned char data[],
uint16_t nbytes = kPanasonicAcStateLength,
uint16_t repeat = kNoRepeat);
#endif

protected:
#ifdef UNIT_TEST
Expand Down
2 changes: 2 additions & 0 deletions src/IRutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ std::string typeToString(const decode_type_t protocol,
case NEC_LIKE: result = "NEC (non-strict)"; break;
case NIKAI: result = "NIKAI"; break;
case PANASONIC: result = "PANASONIC"; break;
case PANASONIC_AC: result = "PANASONIC_AC"; break;
case PRONTO: result = "PRONTO"; break;
case RAW: result = "RAW"; break;
case RC5: result = "RC5"; break;
Expand Down Expand Up @@ -167,6 +168,7 @@ bool hasACState(const decode_type_t protocol) {
case HITACHI_AC2:
case KELVINATOR:
case MITSUBISHI_AC:
case PANASONIC_AC:
case SAMSUNG_AC:
case TOSHIBA_AC:
case WHIRLPOOL_AC:
Expand Down
Loading

0 comments on commit 17d0364

Please sign in to comment.