From 7a39bba272d0630d2ed4168a160f861688be90ae Mon Sep 17 00:00:00 2001
From: Florian <1technophile@users.noreply.github.com>
Date: Sat, 16 Mar 2019 13:16:54 +0100
Subject: [PATCH] update irremote ESP8266 to 2.5.6
---
ZgatewayIR.ino | 25 +-
config_IR.h | 3 +
lib/IRremoteESP8266/.github/Contributors.md | 3 +-
lib/IRremoteESP8266/README.md | 4 +-
lib/IRremoteESP8266/ReleaseNotes.md | 19 +
.../examples/IRMQTTServer/IRMQTTServer.ino | 31 +-
.../examples/IRrecvDumpV2/IRrecvDumpV2.ino | 18 +-
lib/IRremoteESP8266/keywords.txt | 154 ++++++--
lib/IRremoteESP8266/library.json | 2 +-
lib/IRremoteESP8266/library.properties | 2 +-
lib/IRremoteESP8266/src/IRrecv.cpp | 14 +-
lib/IRremoteESP8266/src/IRrecv.h | 17 +-
lib/IRremoteESP8266/src/IRremoteESP8266.h | 30 +-
lib/IRremoteESP8266/src/IRsend.cpp | 206 ++++++----
lib/IRremoteESP8266/src/IRsend.h | 20 +-
lib/IRremoteESP8266/src/IRutils.cpp | 10 +
lib/IRremoteESP8266/src/ir_Coolix.cpp | 161 +++++---
lib/IRremoteESP8266/src/ir_Coolix.h | 8 +-
lib/IRremoteESP8266/src/ir_Daikin.cpp | 30 +-
lib/IRremoteESP8266/src/ir_Daikin.h | 8 +-
lib/IRremoteESP8266/src/ir_Samsung.cpp | 123 +++++-
lib/IRremoteESP8266/src/ir_Tcl.cpp | 253 ++++++++++++
lib/IRremoteESP8266/src/ir_Tcl.h | 69 ++++
lib/IRremoteESP8266/src/ir_Teco.cpp | 243 ++++++++++++
lib/IRremoteESP8266/src/ir_Teco.h | 135 +++++++
lib/IRremoteESP8266/src/ir_Vestel.cpp | 365 ++++++++++--------
lib/IRremoteESP8266/src/ir_Vestel.h | 164 ++++----
lib/IRremoteESP8266/test/IRsend_test.cpp | 310 ++++++++++++++-
lib/IRremoteESP8266/test/Makefile | 26 +-
lib/IRremoteESP8266/test/ir_Coolix_test.cpp | 111 +++++-
lib/IRremoteESP8266/test/ir_LG_test.cpp | 51 +++
lib/IRremoteESP8266/test/ir_Samsung_test.cpp | 145 ++++++-
lib/IRremoteESP8266/test/ir_Tcl_test.cpp | 247 ++++++++++++
lib/IRremoteESP8266/test/ir_Teco_test.cpp | 356 +++++++++++++++++
lib/IRremoteESP8266/test/ir_Vestel_test.cpp | 182 ++++-----
lib/IRremoteESP8266/tools/Makefile | 8 +-
36 files changed, 3023 insertions(+), 530 deletions(-)
create mode 100644 lib/IRremoteESP8266/src/ir_Tcl.cpp
create mode 100644 lib/IRremoteESP8266/src/ir_Tcl.h
create mode 100644 lib/IRremoteESP8266/src/ir_Teco.cpp
create mode 100644 lib/IRremoteESP8266/src/ir_Teco.h
create mode 100644 lib/IRremoteESP8266/test/ir_Tcl_test.cpp
create mode 100644 lib/IRremoteESP8266/test/ir_Teco_test.cpp
diff --git a/ZgatewayIR.ino b/ZgatewayIR.ino
index 17ad2b9..ff88c5f 100644
--- a/ZgatewayIR.ino
+++ b/ZgatewayIR.ino
@@ -759,8 +759,29 @@ boolean sendIdentifiedProtocol(const char * protocol_name, unsigned long data, u
#endif
#ifdef IR_VESTEL_AC
if (strstr(protocol_name, "IR_VESTEL_AC") != NULL){
- if (valueBITS == 0) valueBITS = kVestelACBits;
- irsend.sendVestelAC(data, valueBITS, valueRPT);
+ if (valueBITS == 0) valueBITS = kVestelAcBits;
+ irsend.sendVestelAc(data, valueBITS, valueRPT);
+ return true;
+ }
+ #endif
+ #ifdef IR_SAMSUNG36
+ if (strstr(protocol_name, "IR_SAMSUNG36") != NULL){
+ if (valueBITS == 0) valueBITS = kSamsung36Bits;
+ irsend.sendSamsung36(data, valueBITS, valueRPT);
+ return true;
+ }
+ #endif
+ #ifdef IR_TCL112AC
+ if (strstr(protocol_name, "IR_TCL112AC") != NULL){
+ if (valueBITS == 0) valueBITS = kTcl112AcStateLength;
+ irsend.sendTcl112Ac(datastring, valueBITS, valueRPT);
+ return true;
+ }
+ #endif
+ #ifdef IR_TECO
+ if (strstr(protocol_name, "IR_TECO") != NULL){
+ if (valueBITS == 0) valueBITS = kTecoBits;
+ irsend.sendTeco(data, valueBITS, valueRPT);
return true;
}
#endif
diff --git a/config_IR.h b/config_IR.h
index b4c9a03..ee51b35 100644
--- a/config_IR.h
+++ b/config_IR.h
@@ -95,6 +95,9 @@
#define IR_MWM
#define IR_DAIKIN2
#define IR_VESTEL_AC
+ #define IR_SAMSUNG36
+ #define IR_TCL112AC
+ #define IR_TECO
#elif ESP32
#define IR_Raw
#define IR_COOLIX
diff --git a/lib/IRremoteESP8266/.github/Contributors.md b/lib/IRremoteESP8266/.github/Contributors.md
index 5f75ea3..a330f1b 100644
--- a/lib/IRremoteESP8266/.github/Contributors.md
+++ b/lib/IRremoteESP8266/.github/Contributors.md
@@ -12,7 +12,8 @@
- [Jorge Cisneros](https://github.com/jorgecis/)
- [Denes Varga](https://github.com/denxhun/)
- [Brett T. Warden](https://github.com/bwarden/)
+- [Fabien Valthier](https://github.com/hcoohb)
-All contributors can be found on the [contributors site](https://github.com/markszabo/IRremoteESP8266/graphs/contributors).
+All contributors can be found on the [contributors site](https://github.com/markszabo/IRremoteESP8266/graphs/contributors).
### Contributors of the [original project](https://github.com/z3t0/Arduino-IRremote) can be found on the [original project's contributors page](https://github.com/z3t0/Arduino-IRremote/blob/master/Contributors.md)
diff --git a/lib/IRremoteESP8266/README.md b/lib/IRremoteESP8266/README.md
index a179214..03c09a2 100644
--- a/lib/IRremoteESP8266/README.md
+++ b/lib/IRremoteESP8266/README.md
@@ -8,8 +8,8 @@
This library enables you to **send _and_ receive** infra-red signals on an [ESP8266 using the Arduino framework](https://github.com/esp8266/Arduino) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* etc.
-## v2.5.5 Now Available
-Version 2.5.5 of the library is now [available](https://github.com/markszabo/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes.
+## v2.5.6 Now Available
+Version 2.5.6 of the library is now [available](https://github.com/markszabo/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes.
#### Upgrading from pre-v2.0
Usage of the library has been slightly changed in v2.0. You will need to change your usage to work with v2.0 and beyond. You can read more about the changes required on our [Upgrade to v2.0](https://github.com/markszabo/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.
diff --git a/lib/IRremoteESP8266/ReleaseNotes.md b/lib/IRremoteESP8266/ReleaseNotes.md
index 533b952..ed7c710 100644
--- a/lib/IRremoteESP8266/ReleaseNotes.md
+++ b/lib/IRremoteESP8266/ReleaseNotes.md
@@ -1,5 +1,24 @@
# Release Notes
+## _v2.5.6 (20190316)_
+
+**[Bug Fixes]**
+- Fix Coolix A/C Class to handle special states better. (#633, #624)
+
+**[Features]**
+- Fix case style for recent A/C protocols. (#631)
+- Update `IRsend::send()` to include all simple protocols. (#629, #628)
+- Experimental basic support for 112 bit TCL AC messages (#627, #619)
+- Add support for TECO AC (#622)
+- Experimental support for Samsung 36 bit protocol (#625, #621)
+
+**[Misc]**
+- Set Coolix to default to 1 repeat. (#637, #636, #624, #439)
+- Set Daikin2 modulation to 36.7kHz. (#635)
+- Refactor IRVestelAC class to use portable code. (#617)
+- Adjust Daikin2 timings and tolerance. (#616, #582)
+
+
## _v2.5.5 (20190207)_
**[Bug Fixes]**
diff --git a/lib/IRremoteESP8266/examples/IRMQTTServer/IRMQTTServer.ino b/lib/IRremoteESP8266/examples/IRMQTTServer/IRMQTTServer.ino
index 250e8b6..a1e8d23 100644
--- a/lib/IRremoteESP8266/examples/IRMQTTServer/IRMQTTServer.ino
+++ b/lib/IRremoteESP8266/examples/IRMQTTServer/IRMQTTServer.ino
@@ -261,7 +261,7 @@ const uint16_t kMinUnknownSize = 2 * 10;
// ----------------- End of User Configuration Section -------------------------
// Globals
-#define _MY_VERSION_ "v0.8.3"
+#define _MY_VERSION_ "v0.8.4"
// HTML arguments we will parse for IR code information.
#define argType "type"
#define argData "code"
@@ -467,12 +467,14 @@ void handleRoot() {
""
""
""
+ ""
""
""
""
""
""
""
+ ""
""
""
" Code: 0xMitsubishi"
""
""
+ ""
""
""
""
@@ -723,6 +726,9 @@ bool parseStringAndSendAirCon(const uint16_t irType, const String str) {
// Cap the maximum size.
stateSize = std::min(stateSize, kStateSizeMax);
break;
+ case TCL112AC:
+ stateSize = kTcl112AcStateLength;
+ break;
default: // Not a protocol we expected. Abort.
debug("Unexpected AirCon protocol detected. Ignoring.");
return false;
@@ -852,6 +858,11 @@ bool parseStringAndSendAirCon(const uint16_t irType, const String str) {
case MWM:
irsend.sendMWM(reinterpret_cast(state), stateSize);
break;
+#endif
+#if SEND_TCL112AC
+ case TCL112AC:
+ irsend.sendTcl112Ac(reinterpret_cast(state));
+ break;
#endif
default:
debug("Unexpected AirCon type in send request. Not sent.");
@@ -1413,6 +1424,13 @@ bool sendIRCode(int const ir_type, uint64_t const code, char const * code_str,
irsend.sendSAMSUNG(code, bits, repeat);
break;
#endif
+#if SEND_SAMSUNG36
+ case SAMSUNG36: // 56
+ if (bits == 0)
+ bits = kSamsung36Bits;
+ irsend.sendSamsung36(code, bits, repeat);
+ break;
+#endif
#if SEND_WHYNTER
case WHYNTER: // 8
if (bits == 0)
@@ -1612,8 +1630,15 @@ bool sendIRCode(int const ir_type, uint64_t const code, char const * code_str,
#if SEND_VESTEL_AC
case VESTEL_AC: // 54
if (bits == 0)
- bits = kVestelACBits;
- irsend.sendVestelAC(code, bits, repeat);
+ bits = kVestelAcBits;
+ irsend.sendVestelAc(code, bits, repeat);
+ break;
+#endif
+#if SEND_TECO
+ case TECO: // 55
+ if (bits == 0)
+ bits = kTecoBits;
+ irsend.sendTeco(code, bits, repeat);
break;
#endif
default:
diff --git a/lib/IRremoteESP8266/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/lib/IRremoteESP8266/examples/IRrecvDumpV2/IRrecvDumpV2.ino
index 515d6a0..9e8c3e1 100644
--- a/lib/IRremoteESP8266/examples/IRrecvDumpV2/IRrecvDumpV2.ino
+++ b/lib/IRremoteESP8266/examples/IRrecvDumpV2/IRrecvDumpV2.ino
@@ -37,6 +37,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -225,11 +227,25 @@ void dumpACInfo(decode_results *results) {
#endif // DECODE_WHIRLPOOL_AC
#if DECODE_VESTEL_AC
if (results->decode_type == VESTEL_AC) {
- IRVestelAC ac(0);
+ IRVestelAc ac(0);
ac.setRaw(results->value); // Like Coolix, use value instead of state.
description = ac.toString();
}
#endif // DECODE_VESTEL_AC
+#if DECODE_TECO
+ if (results->decode_type == TECO) {
+ IRTecoAc ac(0);
+ ac.setRaw(results->value); // Like Coolix, use value instead of state.
+ description = ac.toString();
+ }
+#endif // DECODE_TECO
+#if DECODE_TCL112AC
+ if (results->decode_type == TCL112AC) {
+ IRTcl112Ac ac(0);
+ ac.setRaw(results->state);
+ description = ac.toString();
+ }
+#endif // DECODE_TCL112AC
// If we got a human-readable description of the message, display it.
if (description != "") Serial.println("Mesg Desc.: " + description);
}
diff --git a/lib/IRremoteESP8266/keywords.txt b/lib/IRremoteESP8266/keywords.txt
index bf72a58..f40cbdc 100644
--- a/lib/IRremoteESP8266/keywords.txt
+++ b/lib/IRremoteESP8266/keywords.txt
@@ -34,9 +34,11 @@ IRMideaAC KEYWORD1
IRMitsubishiAC KEYWORD1
IRPanasonicAc KEYWORD1
IRSamsungAc KEYWORD1
+IRTcl112Ac KEYWORD1
+IRTecoAc KEYWORD1
IRToshibaAC KEYWORD1
IRTrotecESP KEYWORD1
-IRVestelAC KEYWORD1
+IRVestelAc KEYWORD1
IRWhirlpoolAc KEYWORD1
IRrecv KEYWORD1
IRsend KEYWORD1
@@ -111,13 +113,16 @@ decodeRC5 KEYWORD2
decodeRC6 KEYWORD2
decodeRCMM KEYWORD2
decodeSAMSUNG KEYWORD2
+decodeSamsung36 KEYWORD2
decodeSamsungAC KEYWORD2
decodeSanyo KEYWORD2
decodeSanyoLC7461 KEYWORD2
decodeSharp KEYWORD2
decodeSony KEYWORD2
+decodeTcl112Ac KEYWORD2
+decodeTeco KEYWORD2
decodeToshibaAC KEYWORD2
-decodeVestelAC KEYWORD2
+decodeVestelAc KEYWORD2
decodeWhirlpoolAC KEYWORD2
decodeWhynter KEYWORD2
disableIRIn KEYWORD2
@@ -177,6 +182,7 @@ getMax KEYWORD2
getMode KEYWORD2
getMold KEYWORD2
getNight KEYWORD2
+getNormalState KEYWORD2
getOffTime KEYWORD2
getOffTimer KEYWORD2
getOffTimerEnabled KEYWORD2
@@ -217,9 +223,13 @@ getZoneFollow KEYWORD2
getiFeel KEYWORD2
hasACState KEYWORD2
invertBits KEYWORD2
+isOffTimerActive KEYWORD2
isOffTimerEnabled KEYWORD2
+isOnTimerActive KEYWORD2
isOnTimerEnabled KEYWORD2
+isSpecialState KEYWORD2
isTimeCommand KEYWORD2
+isTimerActive KEYWORD2
isTimerEnabled KEYWORD2
ledOff KEYWORD2
ledOn KEYWORD2
@@ -233,6 +243,7 @@ off KEYWORD2
on KEYWORD2
printState KEYWORD2
readbits KEYWORD2
+recoverSavedState KEYWORD2
renderTime KEYWORD2
reset KEYWORD2
resultToHexidecimal KEYWORD2
@@ -287,15 +298,18 @@ sendRC6 KEYWORD2
sendRCMM KEYWORD2
sendRaw KEYWORD2
sendSAMSUNG KEYWORD2
+sendSamsung36 KEYWORD2
sendSamsungAC KEYWORD2
sendSanyoLC7461 KEYWORD2
sendSharp KEYWORD2
sendSharpRaw KEYWORD2
sendSherwood KEYWORD2
sendSony KEYWORD2
+sendTcl112Ac KEYWORD2
+sendTeco KEYWORD2
sendToshibaAC KEYWORD2
sendTrotec KEYWORD2
-sendVestelAC KEYWORD2
+sendVestelAc KEYWORD2
sendWhirlpoolAC KEYWORD2
sendWhynter KEYWORD2
serialPrintUint64 KEYWORD2
@@ -330,7 +344,9 @@ setModel KEYWORD2
setMold KEYWORD2
setNight KEYWORD2
setOffTimer KEYWORD2
+setOffTimerActive KEYWORD2
setOnTimer KEYWORD2
+setOnTimerActive KEYWORD2
setPower KEYWORD2
setPowerToggle KEYWORD2
setPowerful KEYWORD2
@@ -353,6 +369,7 @@ setTemp KEYWORD2
setTempRaw KEYWORD2
setTime KEYWORD2
setTimer KEYWORD2
+setTimerActive KEYWORD2
setTurbo KEYWORD2
setUnknownThreshold KEYWORD2
setVane KEYWORD2
@@ -372,6 +389,7 @@ toggleRC5 KEYWORD2
toggleRC6 KEYWORD2
typeToString KEYWORD2
uint64ToString KEYWORD2
+updateSavedState KEYWORD2
validChecksum KEYWORD2
xorBytes KEYWORD2
@@ -467,11 +485,14 @@ DECODE_RC5 LITERAL1
DECODE_RC6 LITERAL1
DECODE_RCMM LITERAL1
DECODE_SAMSUNG LITERAL1
+DECODE_SAMSUNG36 LITERAL1
DECODE_SAMSUNG_AC LITERAL1
DECODE_SANYO LITERAL1
DECODE_SHARP LITERAL1
DECODE_SHERWOOD LITERAL1
DECODE_SONY LITERAL1
+DECODE_TCL112AC LITERAL1
+DECODE_TECO LITERAL1
DECODE_TOSHIBA_AC LITERAL1
DECODE_TROTEC LITERAL1
DECODE_VESTEL_AC LITERAL1
@@ -689,6 +710,7 @@ RC6_MODE0_BITS LITERAL1
RCMM LITERAL1
RCMM_BITS LITERAL1
SAMSUNG LITERAL1
+SAMSUNG36 LITERAL1
SAMSUNG_AC LITERAL1
SAMSUNG_BITS LITERAL1
SANYO LITERAL1
@@ -735,11 +757,14 @@ SEND_RC5 LITERAL1
SEND_RC6 LITERAL1
SEND_RCMM LITERAL1
SEND_SAMSUNG LITERAL1
+SEND_SAMSUNG36 LITERAL1
SEND_SAMSUNG_AC LITERAL1
SEND_SANYO LITERAL1
SEND_SHARP LITERAL1
SEND_SHERWOOD LITERAL1
SEND_SONY LITERAL1
+SEND_TCL112AC LITERAL1
+SEND_TECO LITERAL1
SEND_TOSHIBA_AC LITERAL1
SEND_TROTEC LITERAL1
SEND_VESTEL_AC LITERAL1
@@ -753,6 +778,8 @@ SONY LITERAL1
SONY_12_BITS LITERAL1
SONY_15_BITS LITERAL1
SONY_20_BITS LITERAL1
+TCL112AC LITERAL1
+TECO LITERAL1
TIMEOUT_MS LITERAL1
TOSHIBA_AC LITERAL1
TOSHIBA_AC_AUTO LITERAL1
@@ -887,6 +914,7 @@ kDaikin2BitPurify LITERAL1
kDaikin2BitSleepTimer LITERAL1
kDaikin2Bits LITERAL1
kDaikin2DefaultRepeat LITERAL1
+kDaikin2Freq LITERAL1
kDaikin2Gap LITERAL1
kDaikin2HdrMark LITERAL1
kDaikin2HdrSpace LITERAL1
@@ -905,6 +933,7 @@ kDaikin2SwingVBreeze LITERAL1
kDaikin2SwingVCirculate LITERAL1
kDaikin2SwingVHigh LITERAL1
kDaikin2SwingVLow LITERAL1
+kDaikin2Tolerance LITERAL1
kDaikin2ZeroSpace LITERAL1
kDaikinAuto LITERAL1
kDaikinBeepLoud LITERAL1
@@ -957,6 +986,7 @@ kDaikinStateLength LITERAL1
kDaikinTolerance LITERAL1
kDaikinUnusedTime LITERAL1
kDaikinZeroSpace LITERAL1
+kDefaultMessageGap LITERAL1
kDenonBitMark LITERAL1
kDenonBitMarkTicks LITERAL1
kDenonBits LITERAL1
@@ -1554,6 +1584,7 @@ kRcmmRptLengthTicks LITERAL1
kRcmmTick LITERAL1
kRcmmTolerance LITERAL1
kRepeat LITERAL1
+kSamsung36Bits LITERAL1
kSamsungACSectionLength LITERAL1
kSamsungAcAuto LITERAL1
kSamsungAcAutoTemp LITERAL1
@@ -1674,6 +1705,54 @@ kSpaceState LITERAL1
kStartOffset LITERAL1
kStateSizeMax LITERAL1
kStopState LITERAL1
+kTcl112AcAuto LITERAL1
+kTcl112AcBitMark LITERAL1
+kTcl112AcBits LITERAL1
+kTcl112AcCool LITERAL1
+kTcl112AcDefaultRepeat LITERAL1
+kTcl112AcDry LITERAL1
+kTcl112AcFan LITERAL1
+kTcl112AcGap LITERAL1
+kTcl112AcHalfDegree LITERAL1
+kTcl112AcHdrMark LITERAL1
+kTcl112AcHdrSpace LITERAL1
+kTcl112AcHeat LITERAL1
+kTcl112AcOneSpace LITERAL1
+kTcl112AcPowerMask LITERAL1
+kTcl112AcStateLength LITERAL1
+kTcl112AcTempMax LITERAL1
+kTcl112AcTempMin LITERAL1
+kTcl112AcZeroSpace LITERAL1
+kTecoAuto LITERAL1
+kTecoBitMark LITERAL1
+kTecoBits LITERAL1
+kTecoCool LITERAL1
+kTecoDefaultRepeat LITERAL1
+kTecoDry LITERAL1
+kTecoFan LITERAL1
+kTecoFanAuto LITERAL1
+kTecoFanHigh LITERAL1
+kTecoFanLow LITERAL1
+kTecoFanMask LITERAL1
+kTecoFanMed LITERAL1
+kTecoGap LITERAL1
+kTecoHdrMark LITERAL1
+kTecoHdrSpace LITERAL1
+kTecoHeat LITERAL1
+kTecoMaxTemp LITERAL1
+kTecoMinTemp LITERAL1
+kTecoModeMask LITERAL1
+kTecoOneSpace LITERAL1
+kTecoPower LITERAL1
+kTecoReset LITERAL1
+kTecoSleep LITERAL1
+kTecoSwing LITERAL1
+kTecoTempMask LITERAL1
+kTecoTimerHalfH LITERAL1
+kTecoTimerOn LITERAL1
+kTecoTimerTenHr LITERAL1
+kTecoTimerUniHr LITERAL1
+kTecoZeroSpace LITERAL1
kTimeoutMs LITERAL1
kTolerance LITERAL1
kToshibaACBits LITERAL1
@@ -1723,33 +1802,48 @@ kTrotecTimerOn LITERAL1
kTrotecZeroMark LITERAL1
kTrotecZeroSpace LITERAL1
kUnknownThreshold LITERAL1
-kVestelACAuto LITERAL1
-kVestelACBitMark LITERAL1
-kVestelACBits LITERAL1
-kVestelACCRCMask LITERAL1
-kVestelACCool LITERAL1
-kVestelACDry LITERAL1
-kVestelACFan LITERAL1
-kVestelACFanAuto LITERAL1
-kVestelACFanAutoCool LITERAL1
-kVestelACFanAutoHot LITERAL1
-kVestelACFanHigh LITERAL1
-kVestelACFanLow LITERAL1
-kVestelACFanMed LITERAL1
-kVestelACHdrMark LITERAL1
-kVestelACHdrSpace LITERAL1
-kVestelACHeat LITERAL1
-kVestelACIon LITERAL1
-kVestelACMaxTemp LITERAL1
-kVestelACMinTempC LITERAL1
-kVestelACMinTempH LITERAL1
-kVestelACNormal LITERAL1
-kVestelACOneSpace LITERAL1
-kVestelACSleep LITERAL1
-kVestelACSwing LITERAL1
-kVestelACTolerance LITERAL1
-kVestelACTurbo LITERAL1
-kVestelACZeroSpace LITERAL1
+kVestelAcAuto LITERAL1
+kVestelAcBitMark LITERAL1
+kVestelAcBits LITERAL1
+kVestelAcCRCMask LITERAL1
+kVestelAcChecksumOffset LITERAL1
+kVestelAcCool LITERAL1
+kVestelAcDry LITERAL1
+kVestelAcFan LITERAL1
+kVestelAcFanAuto LITERAL1
+kVestelAcFanAutoCool LITERAL1
+kVestelAcFanAutoHot LITERAL1
+kVestelAcFanHigh LITERAL1
+kVestelAcFanLow LITERAL1
+kVestelAcFanMed LITERAL1
+kVestelAcFanOffset LITERAL1
+kVestelAcHdrMark LITERAL1
+kVestelAcHdrSpace LITERAL1
+kVestelAcHeat LITERAL1
+kVestelAcHourOffset LITERAL1
+kVestelAcIon LITERAL1
+kVestelAcIonOffset LITERAL1
+kVestelAcMaxTemp LITERAL1
+kVestelAcMinTempC LITERAL1
+kVestelAcMinTempH LITERAL1
+kVestelAcMinuteOffset LITERAL1
+kVestelAcModeOffset LITERAL1
+kVestelAcNormal LITERAL1
+kVestelAcOffTimeOffset LITERAL1
+kVestelAcOffTimerFlagOffset LITERAL1
+kVestelAcOnTimeOffset LITERAL1
+kVestelAcOnTimerFlagOffset LITERAL1
+kVestelAcOneSpace LITERAL1
+kVestelAcPowerOffset LITERAL1
+kVestelAcSleep LITERAL1
+kVestelAcSwing LITERAL1
+kVestelAcSwingOffset LITERAL1
+kVestelAcTempOffset LITERAL1
+kVestelAcTimerFlagOffset LITERAL1
+kVestelAcTolerance LITERAL1
+kVestelAcTurbo LITERAL1
+kVestelAcTurboSleepOffset LITERAL1
+kVestelAcZeroSpace LITERAL1
kWhirlpoolAcAltTempMask LITERAL1
kWhirlpoolAcAltTempPos LITERAL1
kWhirlpoolAcAuto LITERAL1
diff --git a/lib/IRremoteESP8266/library.json b/lib/IRremoteESP8266/library.json
index e8e33c6..7d5b7c2 100644
--- a/lib/IRremoteESP8266/library.json
+++ b/lib/IRremoteESP8266/library.json
@@ -1,6 +1,6 @@
{
"name": "IRremoteESP8266",
- "version": "2.5.5",
+ "version": "2.5.6",
"keywords": "infrared, ir, remote, esp8266",
"description": "Send and receive infrared signals with multiple protocols (ESP8266)",
"repository":
diff --git a/lib/IRremoteESP8266/library.properties b/lib/IRremoteESP8266/library.properties
index 1237fe8..4c7e413 100644
--- a/lib/IRremoteESP8266/library.properties
+++ b/lib/IRremoteESP8266/library.properties
@@ -1,5 +1,5 @@
name=IRremoteESP8266
-version=2.5.5
+version=2.5.6
author=Sebastien Warin, Mark Szabo, Ken Shirriff, David Conran
maintainer=Mark Szabo, David Conran, Sebastien Warin, Roi Dayan, Massimiliano Pinto
sentence=Send and receive infrared signals with multiple protocols (ESP8266)
diff --git a/lib/IRremoteESP8266/src/IRrecv.cpp b/lib/IRremoteESP8266/src/IRrecv.cpp
index 9e926de..c27222c 100644
--- a/lib/IRremoteESP8266/src/IRrecv.cpp
+++ b/lib/IRremoteESP8266/src/IRrecv.cpp
@@ -364,6 +364,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) {
DPRINTLN("Attempting SAMSUNG decode");
if (decodeSAMSUNG(results)) return true;
#endif
+#if DECODE_SAMSUNG36
+ DPRINTLN("Attempting Samsung36 decode");
+ if (decodeSamsung36(results)) return true;
+#endif
#if DECODE_WHYNTER
DPRINTLN("Attempting Whynter decode");
if (decodeWhynter(results)) return true;
@@ -495,7 +499,15 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) {
#endif
#if DECODE_VESTEL_AC
DPRINTLN("Attempting Vestel AC decode");
- if (decodeVestelAC(results)) return true;
+ if (decodeVestelAc(results)) return true;
+#endif
+#if DECODE_TCL112AC
+ DPRINTLN("Attempting TCL112AC decode");
+ if (decodeTcl112Ac(results)) return true;
+#endif
+#if DECODE_TECO
+ DPRINTLN("Attempting Teco decode");
+ if (decodeTeco(results)) return true;
#endif
#if DECODE_HASH
// decodeHash returns a hash on any input.
diff --git a/lib/IRremoteESP8266/src/IRrecv.h b/lib/IRremoteESP8266/src/IRrecv.h
index 24df9b9..3d5b33f 100644
--- a/lib/IRremoteESP8266/src/IRrecv.h
+++ b/lib/IRremoteESP8266/src/IRrecv.h
@@ -216,6 +216,11 @@ class IRrecv {
bool decodeSAMSUNG(decode_results *results, uint16_t nbits = kSamsungBits,
bool strict = true);
#endif
+#if DECODE_SAMSUNG
+ bool decodeSamsung36(decode_results *results,
+ const uint16_t nbits = kSamsung36Bits,
+ const bool strict = true);
+#endif
#if DECODE_SAMSUNG_AC
bool decodeSamsungAC(decode_results *results, uint16_t nbits = kSamsungAcBits,
bool strict = true);
@@ -335,8 +340,16 @@ class IRrecv {
bool strict = true);
#endif
#if DECODE_VESTEL_AC
- bool decodeVestelAC(decode_results *results, uint16_t nbits = kVestelACBits,
- bool strict = true);
+ bool decodeVestelAc(decode_results *results, uint16_t nbits = kVestelAcBits,
+ bool strict = true);
+#endif
+#if DECODE_TCL112AC
+ bool decodeTcl112Ac(decode_results *results, uint16_t nbits = kTcl112AcBits,
+ bool strict = true);
+#endif
+#if DECODE_TECO
+ bool decodeTeco(decode_results *results, uint16_t nbits = kTecoBits,
+ bool strict = false);
#endif
};
diff --git a/lib/IRremoteESP8266/src/IRremoteESP8266.h b/lib/IRremoteESP8266/src/IRremoteESP8266.h
index 8912d58..b670ed7 100644
--- a/lib/IRremoteESP8266/src/IRremoteESP8266.h
+++ b/lib/IRremoteESP8266/src/IRremoteESP8266.h
@@ -35,6 +35,7 @@
* Trotec AC code by stufisher
* Carrier & Haier AC code by crankyoldgit
* Vestel AC code by Erdem U. Altınyurt
+ * Teco AC code by Fabien Valthier (hcoohb)
*
* GPL license, all text above must be included in any redistribution
****************************************************/
@@ -49,7 +50,7 @@
#endif
// Library Version
-#define _IRREMOTEESP8266_VERSION_ "2.5.5"
+#define _IRREMOTEESP8266_VERSION_ "2.5.6"
// Supported IR protocols
// Each protocol you include costs memory and, during decode, costs time
// Disable (set to false) all the protocols you do not need/want!
@@ -86,6 +87,9 @@
#define DECODE_SAMSUNG true
#define SEND_SAMSUNG true
+#define DECODE_SAMSUNG36 true
+#define SEND_SAMSUNG36 true
+
#define DECODE_SAMSUNG_AC true
#define SEND_SAMSUNG_AC true
@@ -206,12 +210,19 @@
#define DECODE_VESTEL_AC true
#define SEND_VESTEL_AC true
+#define DECODE_TECO true
+#define SEND_TECO true
+
+#define DECODE_TCL112AC true
+#define SEND_TCL112AC 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_PANASONIC_AC || DECODE_MWM || DECODE_DAIKIN2 || DECODE_VESTEL_AC )
+ DECODE_PANASONIC_AC || DECODE_MWM || DECODE_DAIKIN2 || \
+ DECODE_VESTEL_AC || DECODE_TCL112AC)
#define DECODE_AC true // We need some common infrastructure for decoding A/Cs.
#else
#define DECODE_AC false // We don't need that infrastructure.
@@ -280,11 +291,14 @@ enum decode_type_t {
LUTRON,
ELECTRA_AC,
PANASONIC_AC,
- PIONEER, // 50
+ PIONEER, // (50)
LG2,
MWM,
DAIKIN2,
VESTEL_AC,
+ TECO, // (55)
+ SAMSUNG36,
+ TCL112AC,
};
// Message lengths & required repeat values
@@ -296,7 +310,7 @@ const uint16_t kAiwaRcT501MinRepeats = kSingleRepeat;
const uint16_t kArgoStateLength = 12;
const uint16_t kArgoDefaultRepeat = kNoRepeat;
const uint16_t kCoolixBits = 24;
-const uint16_t kCoolixDefaultRepeat = kNoRepeat;
+const uint16_t kCoolixDefaultRepeat = 1;
const uint16_t kCarrierAcBits = 32;
const uint16_t kCarrierAcMinRepeat = kNoRepeat;
// Daikin has a lot of static stuff that is discarded
@@ -373,6 +387,7 @@ const uint16_t kRC6Mode0Bits = 20; // Excludes the 'start' bit.
const uint16_t kRC6_36Bits = 36; // Excludes the 'start' bit.
const uint16_t kRCMMBits = 24;
const uint16_t kSamsungBits = 32;
+const uint16_t kSamsung36Bits = 36;
const uint16_t kSamsungAcStateLength = 14;
const uint16_t kSamsungAcBits = kSamsungAcStateLength * 8;
const uint16_t kSamsungAcExtendedStateLength = 21;
@@ -393,6 +408,11 @@ const uint16_t kSony15Bits = 15;
const uint16_t kSony20Bits = 20;
const uint16_t kSonyMinBits = 12;
const uint16_t kSonyMinRepeat = 2;
+const uint16_t kTcl112AcStateLength = 14;
+const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8;
+const uint16_t kTcl112AcDefaultRepeat = kNoRepeat;
+const uint16_t kTecoBits = 35;
+const uint16_t kTecoDefaultRepeat = kNoRepeat;
const uint16_t kToshibaACStateLength = 9;
const uint16_t kToshibaACBits = kToshibaACStateLength * 8;
const uint16_t kToshibaACMinRepeat = kSingleRepeat;
@@ -402,7 +422,7 @@ const uint16_t kWhirlpoolAcStateLength = 21;
const uint16_t kWhirlpoolAcBits = kWhirlpoolAcStateLength * 8;
const uint16_t kWhirlpoolAcDefaultRepeat = kNoRepeat;
const uint16_t kWhynterBits = 32;
-const uint8_t kVestelACBits = 56;
+const uint8_t kVestelAcBits = 56;
// Legacy defines. (Deprecated)
diff --git a/lib/IRremoteESP8266/src/IRsend.cpp b/lib/IRremoteESP8266/src/IRsend.cpp
index 1dae43d..ad68fa0 100644
--- a/lib/IRremoteESP8266/src/IRsend.cpp
+++ b/lib/IRremoteESP8266/src/IRsend.cpp
@@ -1,6 +1,6 @@
// Copyright 2009 Ken Shirriff
// Copyright 2015 Mark Szabo
-// Copyright 2017 David Conran
+// Copyright 2017,2019 David Conran
#include "IRsend.h"
#ifndef UNIT_TEST
@@ -488,57 +488,24 @@ void IRsend::sendRaw(uint16_t buf[], uint16_t len, uint16_t hz) {
}
#endif // SEND_RAW
-#ifndef UNIT_TEST
-void IRsend::send(uint16_t type, uint64_t data, uint16_t nbits) {
+// Send a simple (up to 64 bits) IR message of a given type.
+// An unknown/unsupported type will do nothing.
+// Args:
+// type: Protocol number/type of the message you want to send.
+// data: The data you want to send (up to 64 bits).
+// nbits: How many bits long the message is to be.
+// Returns:
+// bool: True if it is a type we can attempt to send, false if not.
+bool IRsend::send(decode_type_t type, uint64_t data, uint16_t nbits) {
switch (type) {
-#if SEND_NEC
- case NEC:
- sendNEC(data, nbits);
+#if SEND_AIWA_RC_T501
+ case AIWA_RC_T501:
+ sendAiwaRCT501(data, nbits);
break;
#endif
-#if SEND_SONY
- case SONY:
- sendSony(data, nbits);
- break;
-#endif
-#if SEND_RC5
- case RC5:
- sendRC5(data, nbits);
- break;
-#endif
-#if SEND_RC6
- case RC6:
- sendRC6(data, nbits);
- break;
-#endif
-#if SEND_DISH
- case DISH:
- sendDISH(data, nbits);
- break;
-#endif
-#if SEND_JVC
- case JVC:
- sendJVC(data, nbits);
- break;
-#endif
-#if SEND_SAMSUNG
- case SAMSUNG:
- sendSAMSUNG(data, nbits);
- break;
-#endif
-#if SEND_LG
- case LG:
- sendLG(data, nbits);
- break;
-#endif
-#if SEND_LG
- case LG2:
- sendLG2(data, nbits);
- break;
-#endif
-#if SEND_WHYNTER
- case WHYNTER:
- sendWhynter(data, nbits);
+#if SEND_CARRIER_AC
+ case CARRIER_AC:
+ sendCarrierAC(data, nbits);
break;
#endif
#if SEND_COOLIX
@@ -551,14 +518,52 @@ void IRsend::send(uint16_t type, uint64_t data, uint16_t nbits) {
sendDenon(data, nbits);
break;
#endif
-#if SEND_SHERWOOD
- case SHERWOOD:
- sendSherwood(data, nbits);
+#if SEND_DISH
+ case DISH:
+ sendDISH(data, nbits);
break;
#endif
-#if SEND_RCMM
- case RCMM:
- sendRCMM(data, nbits);
+#if SEND_GICABLE
+ case GICABLE:
+ sendGICable(data, nbits);
+ break;
+#endif
+#if SEND_GREE
+ case GREE:
+ sendGree(data, nbits);
+ break;
+#endif
+#if SEND_JVC
+ case JVC:
+ sendJVC(data, nbits);
+ break;
+#endif
+#if SEND_LASERTAG
+ case LASERTAG:
+ sendLasertag(data, nbits);
+ break;
+#endif
+#if SEND_LG
+ case LG:
+ sendLG(data, nbits);
+ break;
+ case LG2:
+ sendLG2(data, nbits);
+ break;
+#endif
+#if SEND_LUTRON
+ case LUTRON:
+ sendLutron(data, nbits);
+ break;
+#endif
+#if SEND_MAGIQUEST
+ case MAGIQUEST:
+ sendMagiQuest(data, nbits);
+ break;
+#endif
+#if SEND_MIDEA
+ case MIDEA:
+ sendMidea(data, nbits);
break;
#endif
#if SEND_MITSUBISHI
@@ -571,24 +576,20 @@ void IRsend::send(uint16_t type, uint64_t data, uint16_t nbits) {
sendMitsubishi2(data, nbits);
break;
#endif
-#if SEND_SHARP
- case SHARP:
- sendSharpRaw(data, nbits);
+#if SEND_NIKAI
+ case NIKAI:
+ sendNikai(data, nbits);
break;
#endif
-#if SEND_AIWA_RC_T501
- case AIWA_RC_T501:
- sendAiwaRCT501(data, nbits);
+#if SEND_NEC
+ case NEC:
+ case NEC_LIKE:
+ sendNEC(data, nbits);
break;
#endif
-#if SEND_MIDEA
- case MIDEA:
- sendMidea(data, nbits);
- break;
-#endif
-#if SEND_GICABLE
- case GICABLE:
- sendGICable(data, nbits);
+#if SEND_PANASONIC
+ case PANASONIC:
+ sendPanasonic64(data, nbits);
break;
#endif
#if SEND_PIONEER
@@ -596,11 +597,68 @@ void IRsend::send(uint16_t type, uint64_t data, uint16_t nbits) {
sendPioneer(data, nbits);
break;
#endif
-#if SEND_VESTEL_AC
- case VESTEL_AC:
- sendVestelAC(data, nbits);
+#if SEND_RC5
+ case RC5:
+ sendRC5(data, nbits);
break;
#endif
- }
-}
+#if SEND_RC6
+ case RC6:
+ sendRC6(data, nbits);
+ break;
#endif
+#if SEND_RCMM
+ case RCMM:
+ sendRCMM(data, nbits);
+ break;
+#endif
+#if SEND_SAMSUNG
+ case SAMSUNG:
+ sendSAMSUNG(data, nbits);
+ break;
+#endif
+#if SEND_SAMSUNG36
+ case SAMSUNG36:
+ sendSamsung36(data, nbits);
+ break;
+#endif
+#if SEND_SANYO
+ case SANYO_LC7461:
+ sendSanyoLC7461(data, nbits);
+ break;
+#endif
+#if SEND_SHARP
+ case SHARP:
+ sendSharpRaw(data, nbits);
+ break;
+#endif
+#if SEND_SHERWOOD
+ case SHERWOOD:
+ sendSherwood(data, nbits);
+ break;
+#endif
+#if SEND_SONY
+ case SONY:
+ sendSony(data, nbits);
+ break;
+#endif
+#if SEND_TECO
+ case TECO:
+ sendTeco(data, nbits);
+ break;
+#endif
+#if SEND_VESTEL_AC
+ case VESTEL_AC:
+ sendVestelAc(data, nbits);
+ break;
+#endif
+#if SEND_WHYNTER
+ case WHYNTER:
+ sendWhynter(data, nbits);
+ break;
+#endif
+ default:
+ return false;
+ }
+ return true;
+}
diff --git a/lib/IRremoteESP8266/src/IRsend.h b/lib/IRremoteESP8266/src/IRsend.h
index fddbb8f..e446678 100644
--- a/lib/IRremoteESP8266/src/IRsend.h
+++ b/lib/IRremoteESP8266/src/IRsend.h
@@ -28,6 +28,8 @@ const uint8_t kDutyMax = 100; // Percentage
// delayMicroseconds() is only accurate to 16383us.
// Ref: https://www.arduino.cc/en/Reference/delayMicroseconds
const uint16_t kMaxAccurateUsecDelay = 16383;
+// Usecs to wait between messages we don't know the proper gap time.
+const uint32_t kDefaultMessageGap = 1000000;
// Classes
class IRsend {
@@ -66,7 +68,7 @@ class IRsend {
const uint8_t *dataptr, const uint16_t nbytes,
const uint16_t frequency, const bool MSBfirst,
const uint16_t repeat, const uint8_t dutycycle);
- void send(uint16_t type, uint64_t data, uint16_t nbits);
+ bool send(decode_type_t type, uint64_t data, uint16_t nbits);
#if (SEND_NEC || SEND_SHERWOOD || SEND_AIWA_RC_T501 || SEND_SANYO)
void sendNEC(uint64_t data, uint16_t nbits = kNECBits,
uint16_t repeat = kNoRepeat);
@@ -92,6 +94,10 @@ class IRsend {
uint16_t repeat = kNoRepeat);
uint32_t encodeSAMSUNG(uint8_t customer, uint8_t command);
#endif
+#if SEND_SAMSUNG36
+ void sendSamsung36(const uint64_t data, const uint16_t nbits = kSamsung36Bits,
+ const uint16_t repeat = kNoRepeat);
+#endif
#if SEND_SAMSUNG_AC
void sendSamsungAC(unsigned char data[],
uint16_t nbytes = kSamsungAcStateLength,
@@ -309,9 +315,19 @@ class IRsend {
uint16_t repeat = kNoRepeat);
#endif
#if SEND_VESTEL_AC
- void sendVestelAC(const uint64_t data, const uint16_t nbits = kVestelACBits,
+ void sendVestelAc(const uint64_t data, const uint16_t nbits = kVestelAcBits,
const uint16_t repeat = kNoRepeat);
#endif
+#if SEND_TCL112AC
+ void sendTcl112Ac(const unsigned char data[],
+ const uint16_t nbytes = kTcl112AcStateLength,
+ const uint16_t repeat = kTcl112AcDefaultRepeat);
+#endif
+#if SEND_TECO
+ void sendTeco(uint64_t data, uint16_t nbits = kTecoBits,
+ uint16_t repeat = kNoRepeat);
+#endif
+
protected:
#ifdef UNIT_TEST
diff --git a/lib/IRremoteESP8266/src/IRutils.cpp b/lib/IRremoteESP8266/src/IRutils.cpp
index 7c9347d..3397b6b 100644
--- a/lib/IRremoteESP8266/src/IRutils.cpp
+++ b/lib/IRremoteESP8266/src/IRutils.cpp
@@ -231,6 +231,9 @@ std::string typeToString(const decode_type_t protocol, const bool isRepeat) {
case SAMSUNG:
result = "SAMSUNG";
break;
+ case SAMSUNG36:
+ result = "SAMSUNG36";
+ break;
case SAMSUNG_AC:
result = "SAMSUNG_AC";
break;
@@ -249,6 +252,12 @@ std::string typeToString(const decode_type_t protocol, const bool isRepeat) {
case SONY:
result = "SONY";
break;
+ case TCL112AC:
+ result = "TCL112AC";
+ break;
+ case TECO:
+ result = "TECO";
+ break;
case TOSHIBA_AC:
result = "TOSHIBA_AC";
break;
@@ -287,6 +296,7 @@ bool hasACState(const decode_type_t protocol) {
case MWM:
case PANASONIC_AC:
case SAMSUNG_AC:
+ case TCL112AC:
case TOSHIBA_AC:
case WHIRLPOOL_AC:
return true;
diff --git a/lib/IRremoteESP8266/src/ir_Coolix.cpp b/lib/IRremoteESP8266/src/ir_Coolix.cpp
index b0cb0e2..38f1b69 100644
--- a/lib/IRremoteESP8266/src/ir_Coolix.cpp
+++ b/lib/IRremoteESP8266/src/ir_Coolix.cpp
@@ -93,7 +93,7 @@ void IRsend::sendCOOLIX(uint64_t data, uint16_t nbits, uint16_t repeat) {
// https://github.com/markszabo/IRremoteESP8266/issues/484
IRCoolixAC::IRCoolixAC(uint16_t pin) : _irsend(pin) { stateReset(); }
-void IRCoolixAC::stateReset() { remote_state = kCoolixDefaultState; }
+void IRCoolixAC::stateReset() { setRaw(kCoolixDefaultState); }
void IRCoolixAC::begin() { _irsend.begin(); }
@@ -105,15 +105,50 @@ void IRCoolixAC::send(const uint16_t repeat) {
uint32_t IRCoolixAC::getRaw() { return remote_state; }
-void IRCoolixAC::setRaw(const uint32_t new_code) { remote_state = new_code; }
+void IRCoolixAC::setRaw(const uint32_t new_code) {
+ remote_state = new_code;
+ saved_state = new_code;
+}
+
+// Return true if the current state is a special state.
+bool IRCoolixAC::isSpecialState(void) {
+ switch (remote_state) {
+ case kCoolixClean:
+ case kCoolixLed:
+ case kCoolixOff:
+ case kCoolixSwing:
+ case kCoolixSleep:
+ case kCoolixTurbo:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void IRCoolixAC::updateSavedState(void) {
+ if (!isSpecialState()) saved_state = remote_state;
+}
+
+void IRCoolixAC::recoverSavedState(void) {
+ // If the current state is a special one, last known normal one.
+ if (isSpecialState()) remote_state = saved_state;
+ // If the saved_state was also a special state, reset as we expect a normal
+ // state out of all this.
+ if (isSpecialState()) stateReset();
+}
+
+uint32_t IRCoolixAC::getNormalState(void) {
+ return isSpecialState() ? saved_state : remote_state;
+}
void IRCoolixAC::setTempRaw(const uint8_t code) {
+ recoverSavedState();
remote_state &= ~kCoolixTempMask; // Clear the old temp.
remote_state |= (code << 4);
}
uint8_t IRCoolixAC::getTempRaw() {
- return (remote_state & kCoolixTempMask) >> 4;
+ return (getNormalState() & kCoolixTempMask) >> 4;
}
void IRCoolixAC::setTemp(const uint8_t desired) {
@@ -132,6 +167,7 @@ uint8_t IRCoolixAC::getTemp() {
}
void IRCoolixAC::setSensorTempRaw(const uint8_t code) {
+ recoverSavedState();
remote_state &= ~kCoolixSensorTempMask; // Clear previous sensor temp.
remote_state |= ((code & 0xF) << 8);
}
@@ -145,7 +181,8 @@ void IRCoolixAC::setSensorTemp(const uint8_t desired) {
}
uint8_t IRCoolixAC::getSensorTemp() {
- return ((remote_state & kCoolixSensorTempMask) >> 8) + kCoolixSensorTempMin;
+ return ((getNormalState() & kCoolixSensorTempMask) >> 8) +
+ kCoolixSensorTempMin;
}
bool IRCoolixAC::getPower() {
@@ -154,25 +191,35 @@ bool IRCoolixAC::getPower() {
}
void IRCoolixAC::setPower(const bool power) {
- if (!power) remote_state = kCoolixOff;
- // There really is no distinct "on" setting, so do nothing.
+ if (power) {
+ // There really is no distinct "on" setting, just ensure it a normal state.
+ recoverSavedState();
+ } else {
+ updateSavedState();
+ remote_state = kCoolixOff;
+ }
}
bool IRCoolixAC::getSwing() { return remote_state == kCoolixSwing; }
void IRCoolixAC::setSwing() {
// Assumes that repeated sending "swing" toggles the action on the device.
+ updateSavedState();
remote_state = kCoolixSwing;
}
bool IRCoolixAC::getSleep() { return remote_state == kCoolixSleep; }
-void IRCoolixAC::setSleep() { remote_state = kCoolixSleep; }
+void IRCoolixAC::setSleep() {
+ updateSavedState();
+ remote_state = kCoolixSleep;
+}
bool IRCoolixAC::getTurbo() { return remote_state == kCoolixTurbo; }
void IRCoolixAC::setTurbo() {
// Assumes that repeated sending "turbo" toggles the action on the device.
+ updateSavedState();
remote_state = kCoolixTurbo;
}
@@ -180,19 +227,24 @@ bool IRCoolixAC::getLed() { return remote_state == kCoolixLed; }
void IRCoolixAC::setLed() {
// Assumes that repeated sending "Led" toggles the action on the device.
+ updateSavedState();
remote_state = kCoolixLed;
}
bool IRCoolixAC::getClean() { return remote_state == kCoolixClean; }
-void IRCoolixAC::setClean() { remote_state = kCoolixClean; }
+void IRCoolixAC::setClean() {
+ updateSavedState();
+ remote_state = kCoolixClean;
+}
bool IRCoolixAC::getZoneFollow() {
- return remote_state & kCoolixZoneFollowMask;
+ return getNormalState() & kCoolixZoneFollowMask;
}
// Internal use only.
void IRCoolixAC::setZoneFollow(bool state) {
+ recoverSavedState();
if (state) {
remote_state |= kCoolixZoneFollowMask;
} else {
@@ -201,6 +253,7 @@ void IRCoolixAC::setZoneFollow(bool state) {
}
void IRCoolixAC::clearSensorTemp() {
+ recoverSavedState();
setZoneFollow(false);
setSensorTempRaw(kCoolixSensorTempIgnoreCode);
}
@@ -214,6 +267,7 @@ void IRCoolixAC::setMode(const uint8_t mode) {
case kCoolixAuto:
case kCoolixHeat:
case kCoolixDry:
+ recoverSavedState();
remote_state = (remote_state & ~kCoolixModeMask) | (actualmode << 2);
// Force the temp into a known-good state.
setTemp(getTemp());
@@ -222,15 +276,18 @@ void IRCoolixAC::setMode(const uint8_t mode) {
}
uint8_t IRCoolixAC::getMode() {
- uint8_t mode = (remote_state & kCoolixModeMask) >> 2;
+ uint8_t mode = (getNormalState() & kCoolixModeMask) >> 2;
if (mode == kCoolixDry)
if (getTempRaw() == kCoolixFanTempCode) return kCoolixFan;
return mode;
}
-uint8_t IRCoolixAC::getFan() { return (remote_state & kCoolixFanMask) >> 13; }
+uint8_t IRCoolixAC::getFan() {
+ return (getNormalState() & kCoolixFanMask) >> 13;
+}
void IRCoolixAC::setFan(const uint8_t speed) {
+ recoverSavedState();
uint8_t newspeed = speed;
switch (speed) {
case kCoolixFanMin:
@@ -263,6 +320,47 @@ std::string IRCoolixAC::toString() {
result += "Off";
return result; // If it's off, there is no other info.
}
+ // Special modes.
+ if (getSwing()) {
+ result += ", Swing: Toggle";
+ return result;
+ }
+ if (getSleep()) {
+ result += ", Sleep: Toggle";
+ return result;
+ }
+ if (getTurbo()) {
+ result += ", Turbo: Toggle";
+ return result;
+ }
+ if (getLed()) {
+ result += ", Led: Toggle";
+ return result;
+ }
+ if (getClean()) {
+ result += ", Clean: Toggle";
+ return result;
+ }
+ result += ", Mode: " + uint64ToString(getMode());
+ switch (getMode()) {
+ case kCoolixAuto:
+ result += " (AUTO)";
+ break;
+ case kCoolixCool:
+ result += " (COOL)";
+ break;
+ case kCoolixHeat:
+ result += " (HEAT)";
+ break;
+ case kCoolixDry:
+ result += " (DRY)";
+ break;
+ case kCoolixFan:
+ result += " (FAN)";
+ break;
+ default:
+ result += " (UNKNOWN)";
+ }
result += ", Fan: " + uint64ToString(getFan());
switch (getFan()) {
case kCoolixFanAuto:
@@ -289,47 +387,6 @@ std::string IRCoolixAC::toString() {
default:
result += " (UNKNOWN)";
}
- // Special modes.
- if (getSwing()) {
- result += ", Swing: Toggle";
- return result;
- }
- if (getSleep()) {
- result += ", Sleep: Toggle";
- return result;
- }
- if (getTurbo()) {
- result += ", Turbo: Toggle";
- return result;
- }
- if (getLed()) {
- result += ", Led: Toggle";
- return result;
- }
- if (getClean()) {
- result += ", Mode: Self clean";
- return result;
- }
- result += ", Mode: " + uint64ToString(getMode());
- switch (getMode()) {
- case kCoolixAuto:
- result += " (AUTO)";
- break;
- case kCoolixCool:
- result += " (COOL)";
- break;
- case kCoolixHeat:
- result += " (HEAT)";
- break;
- case kCoolixDry:
- result += " (DRY)";
- break;
- case kCoolixFan:
- result += " (FAN)";
- break;
- default:
- result += " (UNKNOWN)";
- }
if (getMode() != kCoolixFan) // Fan mode doesn't have a temperature.
result += ", Temp: " + uint64ToString(getTemp()) + "C";
result += ", Zone Follow: ";
diff --git a/lib/IRremoteESP8266/src/ir_Coolix.h b/lib/IRremoteESP8266/src/ir_Coolix.h
index fa61437..fdc060a 100644
--- a/lib/IRremoteESP8266/src/ir_Coolix.h
+++ b/lib/IRremoteESP8266/src/ir_Coolix.h
@@ -128,13 +128,17 @@ class IRCoolixAC {
#endif
private:
- // The state of the IR remote in IR code form.
- uint32_t remote_state;
+ uint32_t remote_state; // The state of the IR remote in IR code form.
+ uint32_t saved_state; // Copy of the state if we required a special mode.
IRsend _irsend;
void setTempRaw(const uint8_t code);
uint8_t getTempRaw();
void setSensorTempRaw(const uint8_t code);
void setZoneFollow(const bool state);
+ bool isSpecialState(void);
+ void updateSavedState(void);
+ void recoverSavedState(void);
+ uint32_t getNormalState(void);
};
#endif // IR_COOLIX_H_
diff --git a/lib/IRremoteESP8266/src/ir_Daikin.cpp b/lib/IRremoteESP8266/src/ir_Daikin.cpp
index a6e8d9e..946ab8f 100644
--- a/lib/IRremoteESP8266/src/ir_Daikin.cpp
+++ b/lib/IRremoteESP8266/src/ir_Daikin.cpp
@@ -755,18 +755,18 @@ void IRsend::sendDaikin2(unsigned char data[], uint16_t nbytes,
// Leader
sendGeneric(kDaikin2LeaderMark, kDaikin2LeaderSpace,
0, 0, 0, 0, 0, 0, (uint64_t) 0, // No data payload.
- 0, 38000, false, 0, 50);
+ 0, kDaikin2Freq, false, 0, 50);
// Section #1
sendGeneric(kDaikin2HdrMark, kDaikin2HdrSpace, kDaikin2BitMark,
kDaikin2OneSpace, kDaikin2BitMark, kDaikin2ZeroSpace,
kDaikin2BitMark, kDaikin2Gap, data, kDaikin2Section1Length,
- 38000, false, 0, 50);
+ kDaikin2Freq, false, 0, 50);
// Section #2
sendGeneric(kDaikin2HdrMark, kDaikin2HdrSpace, kDaikin2BitMark,
kDaikin2OneSpace, kDaikin2BitMark, kDaikin2ZeroSpace,
kDaikin2BitMark, kDaikin2Gap, data + kDaikin2Section1Length,
nbytes - kDaikin2Section1Length,
- 38000, false, 0, 50);
+ kDaikin2Freq, false, 0, 50);
}
}
#endif // SEND_DAIKIN2
@@ -1354,9 +1354,10 @@ bool IRrecv::decodeDaikin2(decode_results *results, uint16_t nbits,
kDaikin2Section2Length};
// Leader
- if (!matchMark(results->rawbuf[offset++], kDaikin2LeaderMark)) return false;
- if (!matchSpace(results->rawbuf[offset++], kDaikin2LeaderSpace))
- return false;
+ if (!matchMark(results->rawbuf[offset++], kDaikin2LeaderMark,
+ kDaikin2Tolerance)) return false;
+ if (!matchSpace(results->rawbuf[offset++], kDaikin2LeaderSpace,
+ kDaikin2Tolerance)) return false;
// Sections
// Keep reading bytes until we either run out of section or state to fill.
@@ -1365,8 +1366,10 @@ bool IRrecv::decodeDaikin2(decode_results *results, uint16_t nbits,
pos += sectionSize[section];
// Section Header
- if (!matchMark(results->rawbuf[offset++], kDaikin2HdrMark)) return false;
- if (!matchSpace(results->rawbuf[offset++], kDaikin2HdrSpace)) return false;
+ if (!matchMark(results->rawbuf[offset++], kDaikin2HdrMark,
+ kDaikin2Tolerance)) return false;
+ if (!matchSpace(results->rawbuf[offset++], kDaikin2HdrSpace,
+ kDaikin2Tolerance)) return false;
// Section Data
for (; offset <= results->rawlen - 16 && i < pos;
@@ -1375,18 +1378,21 @@ bool IRrecv::decodeDaikin2(decode_results *results, uint16_t nbits,
data_result =
matchData(&(results->rawbuf[offset]), 8, kDaikin2BitMark,
kDaikin2OneSpace, kDaikin2BitMark,
- kDaikin2ZeroSpace, kTolerance, kMarkExcess, false);
+ kDaikin2ZeroSpace, kDaikin2Tolerance, kMarkExcess, false);
if (data_result.success == false) break; // Fail
results->state[i] = (uint8_t)data_result.data;
}
// Section Footer
- if (!matchMark(results->rawbuf[offset++], kDaikin2BitMark)) return false;
+ if (!matchMark(results->rawbuf[offset++], kDaikin2BitMark,
+ kDaikin2Tolerance)) return false;
if (section < kDaikin2Sections - 1) { // Inter-section gaps.
- if (!matchSpace(results->rawbuf[offset++], kDaikin2Gap)) return false;
+ if (!matchSpace(results->rawbuf[offset++], kDaikin2Gap,
+ kDaikin2Tolerance)) return false;
} else { // Last section / End of message gap.
if (offset <= results->rawlen &&
- !matchAtLeast(results->rawbuf[offset++], kDaikin2Gap)) return false;
+ !matchAtLeast(results->rawbuf[offset++], kDaikin2Gap,
+ kDaikin2Tolerance)) return false;
}
}
diff --git a/lib/IRremoteESP8266/src/ir_Daikin.h b/lib/IRremoteESP8266/src/ir_Daikin.h
index c72c80e..4423d47 100644
--- a/lib/IRremoteESP8266/src/ir_Daikin.h
+++ b/lib/IRremoteESP8266/src/ir_Daikin.h
@@ -128,17 +128,19 @@ const uint64_t kDaikinFirstHeader64 =
0b1101011100000000000000001100010100000000001001111101101000010001;
// Another variant of the protocol for the Daikin ARC477A1 remote.
+const uint16_t kDaikin2Freq = 36700; // Modulation Frequency in Hz.
const uint16_t kDaikin2LeaderMark = 10024;
const uint16_t kDaikin2LeaderSpace = 25180;
const uint16_t kDaikin2Gap = kDaikin2LeaderMark + kDaikin2LeaderSpace;
const uint16_t kDaikin2HdrMark = 3500;
const uint16_t kDaikin2HdrSpace = 1728;
-const uint16_t kDaikin2BitMark = 418;
-const uint16_t kDaikin2OneSpace = 1315;
-const uint16_t kDaikin2ZeroSpace = 451;
+const uint16_t kDaikin2BitMark = 460;
+const uint16_t kDaikin2OneSpace = 1270;
+const uint16_t kDaikin2ZeroSpace = 420;
const uint16_t kDaikin2Sections = 2;
const uint16_t kDaikin2Section1Length = 20;
const uint16_t kDaikin2Section2Length = 19;
+const uint8_t kDaikin2Tolerance = kTolerance + 5;
const uint8_t kDaikin2BitSleepTimer = 0b00100000;
const uint8_t kDaikin2BitPurify = 0b00010000;
diff --git a/lib/IRremoteESP8266/src/ir_Samsung.cpp b/lib/IRremoteESP8266/src/ir_Samsung.cpp
index d70e571..6c90e74 100644
--- a/lib/IRremoteESP8266/src/ir_Samsung.cpp
+++ b/lib/IRremoteESP8266/src/ir_Samsung.cpp
@@ -1,5 +1,5 @@
// Copyright 2009 Ken Shirriff
-// Copyright 2017 David Conran
+// Copyright 2017, 2018, 2019 David Conran
#include "ir_Samsung.h"
#include
@@ -168,6 +168,127 @@ bool IRrecv::decodeSAMSUNG(decode_results *results, uint16_t nbits,
}
#endif
+#if SEND_SAMSUNG36
+// Send a Samsung 36-bit formatted message.
+//
+// Args:
+// data: The message to be sent.
+// nbits: The bit size of the message being sent. typically kSamsung36Bits.
+// repeat: The number of times the message is to be repeated.
+//
+// Status: Alpha / Experimental.
+//
+// Note:
+// Protocol is used by Samsung Bluray Remote: ak59-00167a
+//
+// Ref:
+// https://github.com/markszabo/IRremoteESP8266/issues/621
+void IRsend::sendSamsung36(const uint64_t data, const uint16_t nbits,
+ const uint16_t repeat) {
+ if (nbits < 16) return; // To small to send.
+ for (uint16_t r = 0; r <= repeat; r++) {
+ // Block #1 (16 bits)
+ sendGeneric(kSamsungHdrMark, kSamsungHdrSpace,
+ kSamsungBitMark, kSamsungOneSpace,
+ kSamsungBitMark, kSamsungZeroSpace,
+ kSamsungBitMark, kSamsungHdrSpace,
+ data >> (nbits - 16), 16, 38, true, 0, kDutyDefault);
+ // Block #2 (The rest, typically 20 bits)
+ sendGeneric(0, 0, // No header
+ kSamsungBitMark, kSamsungOneSpace,
+ kSamsungBitMark, kSamsungZeroSpace,
+ kSamsungBitMark, kSamsungMinGap, // Gap is just a guess.
+ // Mask off the rest of the bits.
+ data & ((1ULL << (nbits - 16)) - 1),
+ nbits - 16, 38, true, 0, kDutyDefault);
+ }
+}
+#endif // SEND_SAMSUNG36
+
+#if DECODE_SAMSUNG36
+// Decode the supplied Samsung36 message.
+//
+// Args:
+// results: Ptr to the data to decode and where to store the decode result.
+// nbits: Nr. of bits to expect in the data portion.
+// Typically kSamsung36Bits.
+// strict: Flag to indicate if we strictly adhere to the specification.
+// Returns:
+// boolean: True if it can decode it, false if it can't.
+//
+// Status: Alpha / Experimental
+//
+// Note:
+// Protocol is used by Samsung Bluray Remote: ak59-00167a
+//
+// Ref:
+// https://github.com/markszabo/IRremoteESP8266/issues/621
+bool IRrecv::decodeSamsung36(decode_results *results, const uint16_t nbits,
+ const bool strict) {
+ if (results->rawlen < 2 * nbits + kHeader + kFooter * 2 - 1)
+ return false; // Can't possibly be a valid Samsung message.
+ // We need to be looking for > 16 bits to make sense.
+ if (nbits <= 16) return false;
+ if (strict && nbits != kSamsung36Bits)
+ return false; // We expect nbits to be 36 bits of message.
+
+ uint64_t data = 0;
+ uint16_t offset = kStartOffset;
+
+ // Header
+ if (!matchMark(results->rawbuf[offset], kSamsungHdrMark)) return false;
+ // Calculate how long the common tick time is based on the header mark.
+ uint32_t m_tick = results->rawbuf[offset++] * kRawTick / kSamsungHdrMarkTicks;
+ if (!matchSpace(results->rawbuf[offset], kSamsungHdrSpace)) return false;
+ // Calculate how long the common tick time is based on the header space.
+ uint32_t s_tick =
+ results->rawbuf[offset++] * kRawTick / kSamsungHdrSpaceTicks;
+ // Data (Block #1)
+ match_result_t data_result =
+ matchData(&(results->rawbuf[offset]), 16,
+ kSamsungBitMarkTicks * m_tick, kSamsungOneSpaceTicks * s_tick,
+ kSamsungBitMarkTicks * m_tick, kSamsungZeroSpaceTicks * s_tick);
+ if (data_result.success == false) return false;
+ data = data_result.data;
+ offset += data_result.used;
+ uint16_t bitsSoFar = data_result.used / 2;
+ // Footer (Block #1)
+ if (!matchMark(results->rawbuf[offset++], kSamsungBitMarkTicks * m_tick))
+ return false;
+ if (!matchSpace(results->rawbuf[offset++], kSamsungHdrSpaceTicks * s_tick))
+ return false;
+ // Data (Block #2)
+ data_result = matchData(&(results->rawbuf[offset]),
+ nbits - 16,
+ kSamsungBitMarkTicks * m_tick,
+ kSamsungOneSpaceTicks * s_tick,
+ kSamsungBitMarkTicks * m_tick,
+ kSamsungZeroSpaceTicks * s_tick);
+ if (data_result.success == false) return false;
+ data <<= (nbits - 16);
+ data += data_result.data;
+ offset += data_result.used;
+ bitsSoFar += data_result.used / 2;
+ // Footer (Block #2)
+ if (!matchMark(results->rawbuf[offset++], kSamsungBitMarkTicks * m_tick))
+ return false;
+ if (offset < results->rawlen &&
+ !matchAtLeast(results->rawbuf[offset], kSamsungMinGapTicks * s_tick))
+ return false;
+
+ // Compliance
+ if (nbits != bitsSoFar) return false;
+
+ // Success
+ results->bits = bitsSoFar;
+ results->value = data;
+ results->decode_type = SAMSUNG36;
+ results->command = data & ((1ULL << (nbits - 16)) - 1);
+ results->address = data >> (nbits - 16);
+ return true;
+}
+#endif // DECODE_SAMSUNG36
+
#if SEND_SAMSUNG_AC
// Send a Samsung A/C message.
//
diff --git a/lib/IRremoteESP8266/src/ir_Tcl.cpp b/lib/IRremoteESP8266/src/ir_Tcl.cpp
new file mode 100644
index 0000000..39d6ba7
--- /dev/null
+++ b/lib/IRremoteESP8266/src/ir_Tcl.cpp
@@ -0,0 +1,253 @@
+// Copyright 2019 David Conran
+
+#include "ir_Tcl.h"
+#include
+#ifndef ARDUINO
+#include
+#endif
+#include "IRremoteESP8266.h"
+#include "IRutils.h"
+
+// Constants
+
+
+#if SEND_TCL112AC
+void IRsend::sendTcl112Ac(const unsigned char data[], const uint16_t nbytes,
+ const uint16_t repeat) {
+ sendGeneric(kTcl112AcHdrMark, kTcl112AcHdrSpace,
+ kTcl112AcBitMark, kTcl112AcOneSpace,
+ kTcl112AcBitMark, kTcl112AcZeroSpace,
+ kTcl112AcBitMark, kTcl112AcGap,
+ data, nbytes, 38000, false, repeat, 50);
+}
+#endif // SEND_TCL112AC
+
+IRTcl112Ac::IRTcl112Ac(uint16_t pin) : _irsend(pin) { stateReset(); }
+
+void IRTcl112Ac::begin() { this->_irsend.begin(); }
+
+#if SEND_TCL112AC
+void IRTcl112Ac::send(const uint16_t repeat) {
+ this->checksum();
+ this->_irsend.sendTcl112Ac(remote_state, kTcl112AcStateLength, repeat);
+}
+#endif // SEND_TCL112AC
+
+// Calculate the checksum for a given array.
+// Args:
+// state: The array to calculate the checksum over.
+// length: The size of the array.
+// Returns:
+// The 8 bit checksum value.
+uint8_t IRTcl112Ac::calcChecksum(uint8_t state[],
+ const uint16_t length) {
+ if (length)
+ return sumBytes(state, length - 1);
+ else
+ return 0;
+}
+
+// Calculate & set the checksum for the current internal state of the remote.
+void IRTcl112Ac::checksum(const uint16_t length) {
+ // Stored the checksum value in the last byte.
+ if (length > 1)
+ remote_state[length - 1] = calcChecksum(remote_state, length);
+}
+
+// Verify the checksum is valid for a given state.
+// Args:
+// state: The array to verify the checksum of.
+// length: The size of the state.
+// Returns:
+// A boolean.
+bool IRTcl112Ac::validChecksum(uint8_t state[], const uint16_t length) {
+ return (length > 1 && state[length - 1] == calcChecksum(state, length));
+}
+
+void IRTcl112Ac::stateReset() {
+ for (uint8_t i = 0; i < kTcl112AcStateLength; i++)
+ remote_state[i] = 0x0;
+ // A known good state. (On, Cool, 24C)
+ remote_state[0] = 0x23;
+ remote_state[1] = 0xCB;
+ remote_state[2] = 0x26;
+ remote_state[3] = 0x01;
+ remote_state[5] = 0x24;
+ remote_state[6] = 0x03;
+ remote_state[7] = 0x07;
+ remote_state[8] = 0x40;
+ remote_state[13] = 0x03;
+}
+
+uint8_t* IRTcl112Ac::getRaw() {
+ this->checksum();
+ return remote_state;
+}
+
+void IRTcl112Ac::setRaw(const uint8_t new_code[], const uint16_t length) {
+ for (uint8_t i = 0; i < length && i < kTcl112AcStateLength; i++) {
+ remote_state[i] = new_code[i];
+ }
+}
+
+// Set the requested power state of the A/C to on.
+void IRTcl112Ac::on(void) { this->setPower(true); }
+
+// Set the requested power state of the A/C to off.
+void IRTcl112Ac::off(void) { this->setPower(false); }
+
+// Set the requested power state of the A/C.
+void IRTcl112Ac::setPower(const bool on) {
+ if (on)
+ remote_state[5] |= kTcl112AcPowerMask;
+ else
+ remote_state[5] &= ~kTcl112AcPowerMask;
+}
+
+// Return the requested power state of the A/C.
+bool IRTcl112Ac::getPower(void) {
+ return remote_state[5] & kTcl112AcPowerMask;
+}
+
+// Get the requested climate operation mode of the a/c unit.
+// Returns:
+// A uint8_t containing the A/C mode.
+uint8_t IRTcl112Ac::getMode() {
+ return remote_state[6] & 0xF;
+}
+
+// Set the requested climate operation mode of the a/c unit.
+void IRTcl112Ac::setMode(const uint8_t mode) {
+ // If we get an unexpected mode, default to AUTO.
+ switch (mode) {
+ case kTcl112AcAuto:
+ case kTcl112AcCool:
+ case kTcl112AcHeat:
+ case kTcl112AcDry:
+ case kTcl112AcFan:
+ remote_state[6] &= 0xF0;
+ remote_state[6] |= mode;
+ break;
+ default:
+ setMode(kTcl112AcAuto);
+ }
+}
+
+void IRTcl112Ac::setTemp(const float celsius) {
+ // Make sure we have desired temp in the correct range.
+ float safecelsius = std::max(celsius, kTcl112AcTempMin);
+ safecelsius = std::min(safecelsius, kTcl112AcTempMax);
+ // Convert to integer nr. of half degrees.
+ uint8_t nrHalfDegrees = safecelsius * 2;
+ if (nrHalfDegrees & 1) // Do we have a half degree celsius?
+ remote_state[12] |= kTcl112AcHalfDegree; // Add 0.5 degrees
+ else
+ remote_state[12] &= ~kTcl112AcHalfDegree; // Clear the half degree.
+ remote_state[7] &= 0xF0; // Clear temp bits.
+ remote_state[7] |= ((uint8_t)kTcl112AcTempMax - nrHalfDegrees / 2);
+}
+
+float IRTcl112Ac::getTemp() {
+ float result = kTcl112AcTempMax - (remote_state[7] & 0xF);
+ if (remote_state[12] & kTcl112AcHalfDegree) result += 0.5;
+ return result;
+}
+
+// Convert the internal state into a human readable string.
+#ifdef ARDUINO
+String IRTcl112Ac::toString() {
+ String result = "";
+#else
+std::string IRTcl112Ac::toString() {
+ std::string result = "";
+#endif // ARDUINO
+ result += "Power: ";
+ result += (this->getPower() ? "On" : "Off");
+ result += ", Mode: " + uint64ToString(getMode());
+ switch (this->getMode()) {
+ case kTcl112AcAuto:
+ result += " (AUTO)";
+ break;
+ case kTcl112AcCool:
+ result += " (COOL)";
+ break;
+ case kTcl112AcHeat:
+ result += " (HEAT)";
+ break;
+ case kTcl112AcDry:
+ result += " (DRY)";
+ break;
+ case kTcl112AcFan:
+ result += " (FAN)";
+ break;
+ default:
+ result += " (UNKNOWN)";
+ }
+ uint16_t nrHalfDegrees = this->getTemp() * 2;
+ result += ", Temp: " + uint64ToString(nrHalfDegrees / 2);
+ if (nrHalfDegrees & 1) result += ".5";
+ result += "C";
+ return result;
+}
+
+#if DECODE_TCL112AC
+// Decode the supplied TCL112AC message.
+//
+// Args:
+// results: Ptr to the data to decode and where to store the decode result.
+// nbits: The number of data bits to expect. Typically kTcl112AcBits.
+// strict: Flag indicating if we should perform strict matching.
+// Returns:
+// boolean: True if it can decode it, false if it can't.
+//
+// Status: BETA / Appears to mostly work.
+//
+// Ref:
+// https://github.com/markszabo/IRremoteESP8266/issues/619
+bool IRrecv::decodeTcl112Ac(decode_results *results, uint16_t nbits,
+ bool strict) {
+ if (results->rawlen < 2 * nbits + kHeader + kFooter - 1)
+ return false; // Can't possibly be a valid Samsung A/C message.
+ if (strict && nbits != kTcl112AcBits) return false;
+
+ uint16_t offset = kStartOffset;
+ uint16_t dataBitsSoFar = 0;
+ match_result_t data_result;
+
+ // Message Header
+ if (!matchMark(results->rawbuf[offset++], kTcl112AcHdrMark)) return false;
+ if (!matchSpace(results->rawbuf[offset++], kTcl112AcHdrSpace)) return false;
+
+ // Data
+ // Keep reading bytes until we either run out of section or state to fill.
+ for (uint16_t i = 0; offset <= results->rawlen - 16 && i < nbits / 8;
+ i++, dataBitsSoFar += 8, offset += data_result.used) {
+ data_result = matchData(&(results->rawbuf[offset]), 8, kTcl112AcBitMark,
+ kTcl112AcOneSpace, kTcl112AcBitMark,
+ kTcl112AcZeroSpace, kTolerance, 0, false);
+ if (data_result.success == false) {
+ DPRINT("DEBUG: offset = ");
+ DPRINTLN(offset + data_result.used);
+ return false; // Fail
+ }
+ results->state[i] = data_result.data;
+ }
+
+ // Footer
+ if (!matchMark(results->rawbuf[offset++], kTcl112AcBitMark)) return false;
+ if (offset <= results->rawlen &&
+ !matchAtLeast(results->rawbuf[offset++], kTcl112AcGap)) return false;
+ // Compliance
+ // Re-check we got the correct size/length due to the way we read the data.
+ if (dataBitsSoFar != nbits) return false;
+ // Verify we got a valid checksum.
+ if (strict && !IRTcl112Ac::validChecksum(results->state)) return false;
+ // Success
+ results->decode_type = TCL112AC;
+ results->bits = dataBitsSoFar;
+ // No need to record the state as we stored it as we decoded it.
+ // As we use result->state, we don't record value, address, or command as it
+ // is a union data type.
+ return true;
+}
+#endif // DECODE_TCL112AC
diff --git a/lib/IRremoteESP8266/src/ir_Tcl.h b/lib/IRremoteESP8266/src/ir_Tcl.h
new file mode 100644
index 0000000..6bbdee1
--- /dev/null
+++ b/lib/IRremoteESP8266/src/ir_Tcl.h
@@ -0,0 +1,69 @@
+// Copyright 2019 David Conran
+
+#ifndef IR_TCL_H_
+#define IR_TCL_H_
+
+#ifndef UNIT_TEST
+#include
+#else
+#include
+#endif
+#include "IRremoteESP8266.h"
+#include "IRsend.h"
+
+// Constants
+const uint16_t kTcl112AcHdrMark = 3000;
+const uint16_t kTcl112AcHdrSpace = 1650;
+const uint16_t kTcl112AcBitMark = 500;
+const uint16_t kTcl112AcOneSpace = 1050;
+const uint16_t kTcl112AcZeroSpace = 325;
+const uint32_t kTcl112AcGap = 100000; // Just a guess.
+
+const uint8_t kTcl112AcHeat = 1;
+const uint8_t kTcl112AcDry = 2;
+const uint8_t kTcl112AcCool = 3;
+const uint8_t kTcl112AcFan = 7;
+const uint8_t kTcl112AcAuto = 8;
+
+const uint8_t kTcl112AcHalfDegree = 0b00100000;
+const float kTcl112AcTempMax = 31.0;
+const float kTcl112AcTempMin = 16.0;
+const uint8_t kTcl112AcPowerMask = 0x04;
+
+class IRTcl112Ac {
+ public:
+ explicit IRTcl112Ac(uint16_t pin);
+
+#if SEND_TCL112AC
+ void send(const uint16_t repeat = kTcl112AcDefaultRepeat);
+#endif // SEND_TCL
+ void begin(void);
+ uint8_t* getRaw(void);
+ void setRaw(const uint8_t new_code[],
+ const uint16_t length = kTcl112AcStateLength);
+ void on(void);
+ void off(void);
+ void setPower(const bool on);
+ bool getPower(void);
+ void setTemp(const float celsius); // Celsius in 0.5 increments
+ float getTemp(void);
+ void setMode(const uint8_t mode);
+ uint8_t getMode(void);
+ static uint8_t calcChecksum(uint8_t state[],
+ const uint16_t length = kTcl112AcStateLength);
+ static bool validChecksum(uint8_t state[],
+ const uint16_t length = kTcl112AcStateLength);
+#ifdef ARDUINO
+ String toString();
+#else
+ std::string toString();
+#endif
+
+ private:
+ uint8_t remote_state[kTcl112AcStateLength];
+ void stateReset();
+ void checksum(const uint16_t length = kTcl112AcStateLength);
+ IRsend _irsend;
+};
+
+#endif // IR_TCL_H_
diff --git a/lib/IRremoteESP8266/src/ir_Teco.cpp b/lib/IRremoteESP8266/src/ir_Teco.cpp
new file mode 100644
index 0000000..db73839
--- /dev/null
+++ b/lib/IRremoteESP8266/src/ir_Teco.cpp
@@ -0,0 +1,243 @@
+// Copyright 2019 Fabien Valthier
+/*
+Node MCU/ESP8266 Sketch to emulate Teco
+*/
+
+#include "ir_Teco.h"
+#include
+#include "IRremoteESP8266.h"
+#include "IRutils.h"
+#ifndef ARDUINO
+#include
+#endif
+
+// Constants
+// using SPACE modulation.
+const uint16_t kTecoHdrMark = 9000;
+const uint16_t kTecoHdrSpace = 4440;
+const uint16_t kTecoBitMark = 620;
+const uint16_t kTecoOneSpace = 1650;
+const uint16_t kTecoZeroSpace = 580;
+const uint32_t kTecoGap = kDefaultMessageGap; // Made-up value. Just a guess.
+
+#if SEND_TECO
+// Send a Teco A/C message.
+//
+// Args:
+// data: Contents of the message to be sent.
+// nbits: Nr. of bits of data to be sent. Typically kTecoBits.
+// repeat: Nr. of additional times the message is to be sent.
+void IRsend::sendTeco(uint64_t data, uint16_t nbits, uint16_t repeat) {
+ sendGeneric(kTecoHdrMark, kTecoHdrSpace, kTecoBitMark, kTecoOneSpace,
+ kTecoBitMark, kTecoZeroSpace, kTecoBitMark, kTecoGap,
+ data, nbits, 38000, false, repeat, kDutyDefault);
+}
+#endif // SEND_TECO
+
+// Class for decoding and constructing Teco AC messages.
+IRTecoAc::IRTecoAc(const uint16_t pin) : _irsend(pin) { stateReset(); }
+
+void IRTecoAc::begin() { _irsend.begin(); }
+
+#if SEND_TECO
+void IRTecoAc::send(const uint16_t repeat) {
+ _irsend.sendTeco(remote_state, kTecoBits, repeat);
+}
+#endif // SEND_TECO
+
+void IRTecoAc::stateReset(void) {
+ // Mode:auto, Power:Off, fan:auto, temp:16, swing:off, sleep:off
+ remote_state = kTecoReset;
+}
+
+uint64_t IRTecoAc::getRaw(void) { return remote_state; }
+
+void IRTecoAc::setRaw(const uint64_t new_code) { remote_state = new_code; }
+
+void IRTecoAc::on(void) { remote_state |= kTecoPower; }
+
+void IRTecoAc::off(void) { remote_state &= ~kTecoPower; }
+
+void IRTecoAc::setPower(const bool on) {
+ if (on)
+ this->on();
+ else
+ this->off();
+}
+
+bool IRTecoAc::getPower(void) {
+ return (remote_state & kTecoPower) == kTecoPower; }
+
+void IRTecoAc::setTemp(const uint8_t temp) {
+ uint8_t newtemp = temp;
+ newtemp = std::min(newtemp, kTecoMaxTemp);
+ newtemp = std::max(newtemp, kTecoMinTemp);
+ newtemp -= kTecoMinTemp; // 16=0b000
+
+ remote_state &= ~kTecoTempMask; // reinit temp
+ remote_state |= (newtemp << 8);
+}
+
+uint8_t IRTecoAc::getTemp(void) {
+ return ((remote_state & kTecoTempMask) >> 8) + kTecoMinTemp;
+}
+
+// Set the speed of the fan
+void IRTecoAc::setFan(const uint8_t speed) {
+ uint8_t newspeed = speed;
+ switch (speed) {
+ case kTecoFanAuto:
+ case kTecoFanHigh:
+ case kTecoFanMed:
+ case kTecoFanLow:
+ break;
+ default:
+ newspeed = kTecoFanAuto;
+ }
+ remote_state &= ~kTecoFanMask; // reinit fan
+ remote_state |= (newspeed << 4);
+}
+
+uint8_t IRTecoAc::getFan(void) { return (remote_state & kTecoFanMask) >> 4; }
+
+void IRTecoAc::setMode(const uint8_t mode) {
+ uint8_t newmode = mode;
+ switch (mode) {
+ case kTecoAuto:
+ case kTecoCool:
+ case kTecoDry:
+ case kTecoFan:
+ case kTecoHeat:
+ break;
+ default:
+ newmode = kTecoAuto;
+ }
+ remote_state &= ~kTecoModeMask; // reinit mode
+ remote_state |= newmode;
+}
+
+uint8_t IRTecoAc::getMode(void) { return remote_state & kTecoModeMask; }
+
+void IRTecoAc::setSwing(const bool on) {
+ if (on)
+ remote_state |= kTecoSwing;
+ else
+ remote_state &= ~kTecoSwing;
+}
+
+bool IRTecoAc::getSwing(void) { return remote_state & kTecoSwing; }
+
+void IRTecoAc::setSleep(const bool on) {
+ if (on)
+ remote_state |= kTecoSleep;
+ else
+ remote_state &= ~kTecoSleep;
+}
+
+bool IRTecoAc::getSleep(void) { return remote_state & kTecoSleep; }
+
+// Convert the internal state into a human readable string.
+#ifdef ARDUINO
+String IRTecoAc::toString(void) {
+ String result = "";
+#else
+std::string IRTecoAc::toString(void) {
+ std::string result = "";
+#endif // ARDUINO
+ result += "Power: ";
+ result += (this->getPower() ? "On" : "Off");
+ result += ", Mode: " + uint64ToString(this->getMode());
+ switch (this->getMode()) {
+ case kTecoAuto:
+ result += " (AUTO)";
+ break;
+ case kTecoCool:
+ result += " (COOL)";
+ break;
+ case kTecoHeat:
+ result += " (HEAT)";
+ break;
+ case kTecoDry:
+ result += " (DRY)";
+ break;
+ case kTecoFan:
+ result += " (FAN)";
+ break;
+ default:
+ result += " (UNKNOWN)";
+ }
+ result += ", Temp: " + uint64ToString(this->getTemp()) + "C";
+ result += ", Fan: " + uint64ToString(this->getFan());
+ switch (this->getFan()) {
+ case kTecoFanAuto:
+ result += " (Auto)";
+ break;
+ case kTecoFanHigh:
+ result += " (High)";
+ break;
+ case kTecoFanLow:
+ result += " (Low)";
+ break;
+ case kTecoFanMed:
+ result += " (Med)";
+ break;
+ default:
+ result += " (UNKNOWN)";
+ }
+ result += ", Sleep: ";
+ result += (this->getSleep() ? "On" : "Off");
+ result += ", Swing: ";
+ result += (this->getSwing() ? "On" : "Off");
+ return result;
+}
+
+#if DECODE_TECO
+// Decode the supplied Teco message.
+//
+// Args:
+// results: Ptr to the data to decode and where to store the decode result.
+// nbits: The number of data bits to expect. Typically kTecoBits.
+// strict: Flag indicating if we should perform strict matching.
+// Returns:
+// boolean: True if it can decode it, false if it can't.
+//
+// Status: STABLE / Tested.
+bool IRrecv::decodeTeco(decode_results* results, uint16_t nbits, bool strict) {
+ // Check if can possibly be a valid Teco message.
+ if (results->rawlen < 2 * nbits + kHeader + kFooter - 1) return false;
+ if (strict && nbits != kTecoBits) return false; // Not what is expected
+
+ uint64_t data = 0;
+ uint16_t offset = kStartOffset;
+ match_result_t data_result;
+
+ // Header
+ if (!matchMark(results->rawbuf[offset++], kTecoHdrMark)) return false;
+ if (!matchSpace(results->rawbuf[offset++], kTecoHdrSpace)) return false;
+ // Data (35 bits)
+ data_result =
+ matchData(&(results->rawbuf[offset]), 35, kTecoBitMark, kTecoOneSpace,
+ kTecoBitMark, kTecoZeroSpace, kTolerance, kMarkExcess, false);
+ if (data_result.success == false) return false;
+ data = data_result.data;
+ offset += data_result.used;
+ uint16_t actualBits = data_result.used / 2;
+
+ // Footer.
+ if (!matchMark(results->rawbuf[offset++], kTecoBitMark)) return false;
+ if (offset < results->rawlen &&
+ !matchAtLeast(results->rawbuf[offset], kTecoGap)) return false;
+
+ // Compliance
+ if (actualBits < nbits) return false;
+ if (strict && actualBits != nbits) return false; // Not as we expected.
+
+ // Success
+ results->decode_type = TECO;
+ results->bits = actualBits;
+ results->value = data;
+ results->address = 0;
+ results->command = 0;
+ return true;
+}
+#endif // DECODE_TECO
diff --git a/lib/IRremoteESP8266/src/ir_Teco.h b/lib/IRremoteESP8266/src/ir_Teco.h
new file mode 100644
index 0000000..9a020f9
--- /dev/null
+++ b/lib/IRremoteESP8266/src/ir_Teco.h
@@ -0,0 +1,135 @@
+// Copyright 2019 Fabien Valthier
+
+#ifndef IR_TECO_H_
+#define IR_TECO_H_
+
+#ifndef UNIT_TEST
+#include
+#else
+#include
+#endif
+#include "IRremoteESP8266.h"
+#include "IRsend.h"
+
+// Constants. Using LSB to be able to send only 35bits.
+const uint8_t kTecoAuto = 0; // 0b000
+const uint8_t kTecoCool = 1; // 0b001
+const uint8_t kTecoDry = 2; // 0b010
+const uint8_t kTecoFan = 3; // 0b110
+const uint8_t kTecoHeat = 4; // 0b001
+const uint8_t kTecoFanAuto = 0; // 0b00
+const uint8_t kTecoFanHigh = 3; // 0b11
+const uint8_t kTecoFanMed = 2; // 0b10
+const uint8_t kTecoFanLow = 1; // 0b01
+const uint8_t kTecoMinTemp = 16; // 16C
+const uint8_t kTecoMaxTemp = 30; // 30C
+
+const uint64_t kTecoModeMask = 0b00000000000000000000000000000000111;
+const uint64_t kTecoPower = 0b00000000000000000000000000000001000;
+const uint64_t kTecoFanMask = 0b00000000000000000000000000000110000;
+const uint64_t kTecoSwing = 0b00000000000000000000000000001000000;
+const uint64_t kTecoSleep = 0b00000000000000000000000000010000000;
+const uint64_t kTecoTempMask = 0b00000000000000000000000111100000000;
+const uint64_t kTecoTimerHalfH = 0b00000000000000000000001000000000000;
+const uint64_t kTecoTimerTenHr = 0b00000000000000000000110000000000000;
+const uint64_t kTecoTimerOn = 0b00000000000000000001000000000000000;
+const uint64_t kTecoTimerUniHr = 0b00000000000000011110000000000000000;
+const uint64_t kTecoReset = 0b01001010000000000000010000000000000;
+/*
+ (header mark and space)
+ Teco AC map read and to be sent in LSB with number of bits
+
+ byte 0 = Cst 0x02
+ byte 1 = Cst 0x50
+ byte 2:
+ b0-3 = 0b0000
+ b4-7 = Timer hours (unit, not thenth)
+ hours:
+ 0000 (0) = +0 hour
+ 0001 (1) = +1 hour
+ ...
+ 1001 (9) = +9 hours
+ byte 3: = timer and Temperature
+ b0 = Timer (1 = On, 0 = Off)
+ b1-2 = Timer - number of 10hours
+ 10Hours:
+ 00 = 0 * 10hours of timer
+ 01 = 1 * 10 hours of timer
+ 10 = 2 * 10hours of timer
+ b3 = Timer - half hour (1=half hour on, 0 = round hour)
+ b4-7: Degrees C.
+ 0000 (0) = 16C
+ 0001 (1) = 17C
+ 0010 (2) = 18C
+ ...
+ 1101 (13) = 29C
+ 1110 (14) = 30C
+ byte 4: Basics
+ b0 = Sleep Mode (1 = On, 0 = Off)
+ b1 = Vent swing (1 = On, 0 = Off)
+ b2-3 = Fan
+ Fan:
+ 00 = Auto
+ 01 = Fan 1
+ 10 = Fan 2
+ 11 = Fan 3 or higher
+ b4 = Power Status (1 = On, 0 = Off)
+ b5-7 = Modes LSB first
+ Modes:
+ 000 = Auto (temp = 25C)
+ 001 = Cool
+ 010 = Dry (temp = 25C, but not shown)
+ 011 = Fan
+ 100 = Heat
+*/
+
+// Classes
+class IRTecoAc {
+ public:
+ explicit IRTecoAc(const uint16_t pin);
+
+ void stateReset(void);
+#if SEND_TECO
+ void send(const uint16_t repeat = kTecoDefaultRepeat);
+#endif // SEND_TECO
+ void begin(void);
+ void on(void);
+ void off(void);
+
+ void setPower(const bool on);
+ bool getPower(void);
+
+ void setTemp(const uint8_t temp);
+ uint8_t getTemp(void);
+
+ void setFan(const uint8_t fan);
+ uint8_t getFan(void);
+
+ void setMode(const uint8_t mode);
+ uint8_t getMode(void);
+
+ void setSwing(const bool state);
+ bool getSwing(void);
+
+ void setSleep(const bool state);
+ bool getSleep(void);
+
+ // void setTimer(uint8_t time); // To check unit
+ // uint8_t getTimer(uint8_t);
+
+ uint64_t getRaw(void);
+ void setRaw(const uint64_t new_code);
+
+#ifdef ARDUINO
+ String toString(void);
+#else
+ std::string toString(void);
+#endif
+
+ private:
+ // The state of the IR remote in IR code form.
+ uint64_t remote_state;
+ IRsend _irsend;
+};
+
+#endif // IR_TECO_H_
diff --git a/lib/IRremoteESP8266/src/ir_Vestel.cpp b/lib/IRremoteESP8266/src/ir_Vestel.cpp
index 3d3cee1..d9e6355 100644
--- a/lib/IRremoteESP8266/src/ir_Vestel.cpp
+++ b/lib/IRremoteESP8266/src/ir_Vestel.cpp
@@ -1,4 +1,5 @@
// Copyright 2018 Erdem U. Altinyurt
+// Copyright 2019 David Conran
#include "ir_Vestel.h"
#include
@@ -37,14 +38,14 @@
//
// Status: STABLE / Working.
//
-void IRsend::sendVestelAC(const uint64_t data, const uint16_t nbits,
+void IRsend::sendVestelAc(const uint64_t data, const uint16_t nbits,
const uint16_t repeat) {
if (nbits % 8 != 0) return; // nbits is required to be a multiple of 8.
- sendGeneric(kVestelACHdrMark, kVestelACHdrSpace, // Header
- kVestelACBitMark, kVestelACOneSpace, // Data
- kVestelACBitMark, kVestelACZeroSpace, // Data
- kVestelACBitMark, 100000, // Footer + repeat gap
+ sendGeneric(kVestelAcHdrMark, kVestelAcHdrSpace, // Header
+ kVestelAcBitMark, kVestelAcOneSpace, // Data
+ kVestelAcBitMark, kVestelAcZeroSpace, // Data
+ kVestelAcBitMark, 100000, // Footer + repeat gap
data, nbits, 38, false, repeat, 50);
}
#endif
@@ -52,133 +53,146 @@ void IRsend::sendVestelAC(const uint64_t data, const uint16_t nbits,
// Code to emulate Vestel A/C IR remote control unit.
// Initialise the object.
-IRVestelAC::IRVestelAC(uint16_t pin) : _irsend(pin) { stateReset(); }
+IRVestelAc::IRVestelAc(uint16_t pin) : _irsend(pin) { stateReset(); }
// Reset the state of the remote to a known good state/sequence.
-void IRVestelAC::stateReset() {
+void IRVestelAc::stateReset() {
// Power On, Mode Auto, Fan Auto, Temp = 25C/77F
- remote_state.rawCode = 0x0F00D9001FEF201LL;
- remote_time_state.rawCode = 0x00;
+ remote_state = 0x0F00D9001FEF201ULL;
+ remote_time_state = 0x201ULL;
use_time_state = false;
}
// Configure the pin for output.
-void IRVestelAC::begin() {
+void IRVestelAc::begin() {
_irsend.begin();
- stateReset();
}
#if SEND_VESTEL_AC
// Send the current desired state to the IR LED.
-void IRVestelAC::send() {
+void IRVestelAc::send() {
checksum(); // Ensure correct checksum before sending.
uint64_t code_to_send;
if (use_time_state)
- code_to_send = remote_time_state.rawCode;
+ code_to_send = remote_time_state;
else
- code_to_send = remote_state.rawCode;
- _irsend.sendVestelAC(code_to_send);
+ code_to_send = remote_state;
+ _irsend.sendVestelAc(code_to_send);
}
#endif // SEND_VESTEL_AC
// Return the internal state date of the remote.
-uint64_t IRVestelAC::getRaw() {
+uint64_t IRVestelAc::getRaw() {
checksum();
- if (use_time_state) return remote_time_state.rawCode;
- return remote_state.rawCode;
+ if (use_time_state) return remote_time_state;
+ return remote_state;
}
// Override the internal state with the new state.
-void IRVestelAC::setRaw(uint8_t* newState) {
+void IRVestelAc::setRaw(uint8_t* newState) {
uint64_t upState = 0;
for (int i = 0; i < 7; i++)
upState |= static_cast(newState[i]) << (i * 8);
- remote_state.rawCode = upState;
- remote_time_state.rawCode = upState;
+ remote_state = upState;
+ remote_time_state = upState;
}
-void IRVestelAC::setRaw(const uint64_t newState) {
- remote_state.rawCode = newState;
- remote_time_state.rawCode = newState;
+void IRVestelAc::setRaw(const uint64_t newState) {
+ remote_state = newState;
+ remote_time_state = newState;
}
// Set the requested power state of the A/C to on.
-void IRVestelAC::on() { setPower(true); }
+void IRVestelAc::on() { setPower(true); }
// Set the requested power state of the A/C to off.
-void IRVestelAC::off() { setPower(false); }
+void IRVestelAc::off() { setPower(false); }
// Set the requested power state of the A/C.
-void IRVestelAC::setPower(const bool state) {
+void IRVestelAc::setPower(const bool state) {
+ remote_state &= ~((uint64_t)0xF << kVestelAcPowerOffset);
if (state)
- remote_state.power = 0xF;
+ remote_state |= ((uint64_t)0xF << kVestelAcPowerOffset);
else
- remote_state.power = 0xC;
+ remote_state |= ((uint64_t)0xC << kVestelAcPowerOffset);
use_time_state = false;
}
// Return the requested power state of the A/C.
-bool IRVestelAC::getPower() { return (remote_state.power == 0xF); }
+bool IRVestelAc::getPower() {
+ return (remote_state >> kVestelAcPowerOffset == 0xF);
+}
// Set the temperature in Celsius degrees.
-void IRVestelAC::setTemp(const uint8_t temp) {
+void IRVestelAc::setTemp(const uint8_t temp) {
uint8_t new_temp = temp;
- new_temp = std::max(kVestelACMinTempC, new_temp);
- // new_temp = std::max(kVestelACMinTempH, new_temp); Check MODE
- new_temp = std::min(kVestelACMaxTemp, new_temp);
- remote_state.temp = new_temp - 16;
+ new_temp = std::max(kVestelAcMinTempC, new_temp);
+ // new_temp = std::max(kVestelAcMinTempH, new_temp); Check MODE
+ new_temp = std::min(kVestelAcMaxTemp, new_temp);
+ remote_state &= ~((uint64_t)0xF << kVestelAcTempOffset);
+ remote_state |= (uint64_t)(new_temp - 16) << kVestelAcTempOffset;
use_time_state = false;
}
// Return the set temperature.
-uint8_t IRVestelAC::getTemp(void) { return remote_state.temp + 16; }
+uint8_t IRVestelAc::getTemp(void) {
+ return ((remote_state >> kVestelAcTempOffset) & 0xF) + 16;
+}
// Set the speed of the fan,
// 1-3 set the fan speed, 0 or anything else set it to auto.
-void IRVestelAC::setFan(const uint8_t fan) {
+void IRVestelAc::setFan(const uint8_t fan) {
switch (fan) {
- case kVestelACFanLow:
- case kVestelACFanMed:
- case kVestelACFanHigh:
- case kVestelACFanAutoCool:
- case kVestelACFanAutoHot:
- remote_state.fan = fan;
+ case kVestelAcFanLow:
+ case kVestelAcFanMed:
+ case kVestelAcFanHigh:
+ case kVestelAcFanAutoCool:
+ case kVestelAcFanAutoHot:
+ case kVestelAcFanAuto:
+ remote_state &= ~((uint64_t)0xF << kVestelAcFanOffset);
+ remote_state |= (uint64_t)fan << kVestelAcFanOffset;
break;
default:
- remote_state.fan = kVestelACFanAuto;
+ setFan(kVestelAcFanAuto);
}
use_time_state = false;
}
// Return the requested state of the unit's fan.
-uint8_t IRVestelAC::getFan() { return remote_state.fan; }
+uint8_t IRVestelAc::getFan() {
+ return (remote_state >> kVestelAcFanOffset) & 0xF;
+}
// Get the requested climate operation mode of the a/c unit.
// Returns:
// A uint8_t containing the A/C mode.
-uint8_t IRVestelAC::getMode() { return remote_state.mode; }
+uint8_t IRVestelAc::getMode() {
+ return (remote_state >> kVestelAcModeOffset) & 0xF;
+}
// Set the requested climate operation mode of the a/c unit.
-void IRVestelAC::setMode(const uint8_t mode) {
+void IRVestelAc::setMode(const uint8_t mode) {
// If we get an unexpected mode, default to AUTO.
switch (mode) {
- case kVestelACAuto:
- case kVestelACCool:
- case kVestelACHeat:
- case kVestelACDry:
- case kVestelACFan:
- remote_state.mode = mode;
+ case kVestelAcAuto:
+ case kVestelAcCool:
+ case kVestelAcHeat:
+ case kVestelAcDry:
+ case kVestelAcFan:
+ remote_state &= ~((uint64_t)0xF << kVestelAcModeOffset);
+ remote_state |= (uint64_t)mode << kVestelAcModeOffset;
break;
default:
- remote_state.mode = kVestelACAuto;
+ setMode(kVestelAcAuto);
}
use_time_state = false;
}
+
// Set Auto mode of AC.
-void IRVestelAC::setAuto(const int8_t autoLevel) {
+void IRVestelAc::setAuto(const int8_t autoLevel) {
if (autoLevel < -2 || autoLevel > 2) return;
- setMode(kVestelACAuto);
- setFan((autoLevel < 0 ? kVestelACFanAutoCool : kVestelACFanAutoHot));
+ setMode(kVestelAcAuto);
+ setFan((autoLevel < 0 ? kVestelAcFanAutoCool : kVestelAcFanAutoHot));
if (autoLevel == 2)
setTemp(30);
else if (autoLevel == 1)
@@ -191,124 +205,167 @@ void IRVestelAC::setAuto(const int8_t autoLevel) {
setTemp(17);
}
+void IRVestelAc::setTimerActive(const bool on) {
+ if (on) // activation
+ remote_time_state |= ((uint64_t)1 << kVestelAcTimerFlagOffset);
+ else // deactivate
+ remote_time_state &= ~((uint64_t)1 << kVestelAcTimerFlagOffset);
+ use_time_state = true;
+}
+
+bool IRVestelAc::isTimerActive(void) {
+ return (remote_time_state >> kVestelAcTimerFlagOffset) & 1;
+}
+
// Set Timer option of AC.
// Valid time arguments are 0, 0.5, 1, 2, 3 and 5 hours (in min). 0 disables the
// timer.
-void IRVestelAC::setTimer(const uint16_t minutes) {
- remote_time_state.t_turnOnMinute = 0;
- remote_time_state.t_turnOnHour = 0;
- remote_time_state.t_turnOffHour = minutes / 60;
- remote_time_state.t_turnOffMinute = (minutes % 60) / 10;
- remote_time_state.t_off_active = 0;
- if (minutes) {
- remote_time_state.t_timer_mode = 1;
- // Yes. t_on_active instead of t_off_active.
- remote_time_state.t_on_active = 1;
- } else { // Turn off the timer.
- remote_time_state.t_timer_mode = 0;
- remote_time_state.t_on_active = 0;
- }
+void IRVestelAc::setTimer(const uint16_t minutes) {
+ // Clear both On & Off timers.
+ remote_time_state &= ~((uint64_t)0xFFFF << kVestelAcOffTimeOffset);
+ // Set the "Off" time with the nr of minutes before we turn off.
+ remote_time_state |= (uint64_t)(((minutes / 60) << 3) + (minutes % 60) / 10)
+ << kVestelAcOffTimeOffset;
+ setOffTimerActive(false);
+ // Yes. On Timer instead of Off timer active.
+ setOnTimerActive(minutes != 0);
+ setTimerActive(minutes != 0);
use_time_state = true;
}
-uint16_t IRVestelAC::getTimer(void) { return getOffTimer(); }
+uint16_t IRVestelAc::getTimer(void) { return getOffTimer(); }
// Set the AC's internal clock
-void IRVestelAC::setTime(const uint16_t minutes) {
- remote_time_state.t_hour = minutes / 60;
- remote_time_state.t_minute = minutes % 60;
+void IRVestelAc::setTime(const uint16_t minutes) {
+ remote_time_state &= ~((uint64_t)0x1F << kVestelAcHourOffset);
+ remote_time_state |= (uint64_t)((minutes / 60) & 0x1F)
+ << kVestelAcHourOffset;
+ remote_time_state &= ~((uint64_t)0xFF << kVestelAcMinuteOffset);
+ remote_time_state |= (uint64_t)((minutes % 60) & 0xFF)
+ << kVestelAcMinuteOffset;
use_time_state = true;
}
-uint16_t IRVestelAC::getTime(void) {
- return remote_time_state.t_hour * 60 + remote_time_state.t_minute;
+uint16_t IRVestelAc::getTime(void) {
+ return ((remote_time_state >> kVestelAcHourOffset) & 0x1F) * 60 +
+ ((remote_time_state >> kVestelAcMinuteOffset) & 0xFF);
+}
+
+void IRVestelAc::setOnTimerActive(const bool on) {
+ if (on) // activation
+ remote_time_state |= ((uint64_t)1 << kVestelAcOnTimerFlagOffset);
+ else // deactivate
+ remote_time_state &= ~((uint64_t)1 << kVestelAcOnTimerFlagOffset);
+ use_time_state = true;
+}
+
+bool IRVestelAc::isOnTimerActive(void) {
+ return (remote_time_state >> kVestelAcOnTimerFlagOffset) & 1;
}
// Set AC's wake up time. Takes time in minute.
-void IRVestelAC::setOnTimer(const uint16_t minutes) {
- remote_time_state.t_turnOnHour = minutes / 60;
- // Register is 3 bit and can only hold minute/10
- remote_time_state.t_turnOnMinute = (minutes % 60) / 10;
- if (minutes)
- remote_time_state.t_on_active = 1; // activation
- else
- remote_time_state.t_on_active = 0; // deactivate
- remote_time_state.t_timer_mode = 0;
+void IRVestelAc::setOnTimer(const uint16_t minutes) {
+ remote_time_state &= ~((uint64_t)0xFF << kVestelAcOnTimeOffset);
+ remote_time_state |= (uint64_t)(((minutes / 60) << 3) + (minutes % 60) / 10)
+ << kVestelAcOnTimeOffset;
+ setOnTimerActive(minutes != 0);
+ setTimerActive(false);
use_time_state = true;
}
-uint16_t IRVestelAC::getOnTimer(void) {
- return remote_time_state.t_turnOnHour * 60 +
- remote_time_state.t_turnOnMinute * 10;
+uint16_t IRVestelAc::getOnTimer(void) {
+ uint8_t ontime = (remote_time_state >> kVestelAcOnTimeOffset) & 0xFF;
+ return (ontime >> 3) * 60 + (ontime & 0x7) * 10;
+}
+
+void IRVestelAc::setOffTimerActive(const bool on) {
+ if (on) // activation
+ remote_time_state |= ((uint64_t)1 << kVestelAcOffTimerFlagOffset);
+ else // deactivate
+ remote_time_state &= ~((uint64_t)1 << kVestelAcOffTimerFlagOffset);
+ use_time_state = true;
+}
+
+bool IRVestelAc::isOffTimerActive(void) {
+ return (remote_time_state >> kVestelAcOffTimerFlagOffset) & 1;
}
// Set AC's turn off time. Takes time in minute.
-void IRVestelAC::setOffTimer(const uint16_t minutes) {
- remote_time_state.t_turnOffHour = minutes / 60;
- // Register is 3 bit and can only hold minute/10
- remote_time_state.t_turnOffMinute = (minutes % 60) / 10;
- if (minutes)
- remote_time_state.t_off_active = 1; // activation
- else
- remote_time_state.t_off_active = 0; // deactivate
- remote_time_state.t_timer_mode = 0;
+void IRVestelAc::setOffTimer(const uint16_t minutes) {
+ remote_time_state &= ~((uint64_t)0xFF << kVestelAcOffTimeOffset);
+ remote_time_state |=
+ (uint64_t)((((minutes / 60) << 3) + (minutes % 60) / 10) & 0xFF)
+ << kVestelAcOffTimeOffset;
+ setOffTimerActive(minutes != 0);
+ setTimerActive(false);
use_time_state = true;
}
-uint16_t IRVestelAC::getOffTimer(void) {
- return remote_time_state.t_turnOffHour * 60 +
- remote_time_state.t_turnOffMinute * 10;
+uint16_t IRVestelAc::getOffTimer(void) {
+ uint8_t offtime = (remote_time_state >> kVestelAcOffTimeOffset) & 0xFF;
+ return (offtime >> 3) * 60 + (offtime & 0x7) * 10;
}
// Set the Sleep state of the A/C.
-void IRVestelAC::setSleep(const bool state) {
- remote_state.turbo_sleep_normal = state ? kVestelACSleep : kVestelACNormal;
+void IRVestelAc::setSleep(const bool state) {
+ remote_state &= ~((uint64_t)0xF << kVestelAcTurboSleepOffset);
+ remote_state |= (uint64_t)(state ? kVestelAcSleep : kVestelAcNormal)
+ << kVestelAcTurboSleepOffset;
use_time_state = false;
}
// Return the Sleep state of the A/C.
-bool IRVestelAC::getSleep() {
- return remote_state.turbo_sleep_normal == kVestelACSleep;
+bool IRVestelAc::getSleep() {
+ return ((remote_state >> kVestelAcTurboSleepOffset) & 0xF) == kVestelAcSleep;
}
// Set the Turbo state of the A/C.
-void IRVestelAC::setTurbo(const bool state) {
- remote_state.turbo_sleep_normal = state ? kVestelACTurbo : kVestelACNormal;
+void IRVestelAc::setTurbo(const bool state) {
+ remote_state &= ~((uint64_t)0xF << kVestelAcTurboSleepOffset);
+ remote_state |= (uint64_t)(state ? kVestelAcTurbo : kVestelAcNormal)
+ << kVestelAcTurboSleepOffset;
use_time_state = false;
}
// Return the Turbo state of the A/C.
-bool IRVestelAC::getTurbo() {
- return remote_state.turbo_sleep_normal == kVestelACTurbo;
+bool IRVestelAc::getTurbo() {
+ return ((remote_state >> kVestelAcTurboSleepOffset) & 0xF) == kVestelAcTurbo;
}
// Set the Ion state of the A/C.
-void IRVestelAC::setIon(const bool state) {
- remote_state.ion = state ? kVestelACIon : 0;
+void IRVestelAc::setIon(const bool state) {
+ remote_state &= ~((uint64_t)0x1 << kVestelAcIonOffset);
+
+ remote_state |= (uint64_t)(state ? 1 : 0) << kVestelAcIonOffset;
use_time_state = false;
}
// Return the Ion state of the A/C.
-bool IRVestelAC::getIon() { return remote_state.ion == kVestelACIon; }
+bool IRVestelAc::getIon() { return (remote_state >> kVestelAcIonOffset) & 1; }
// Set the Swing Roaming state of the A/C.
-void IRVestelAC::setSwing(const bool state) {
- remote_state.swing = state ? kVestelACSwing : 0xF;
+void IRVestelAc::setSwing(const bool state) {
+ remote_state &= ~((uint64_t)0xF << kVestelAcSwingOffset);
+
+ remote_state |= (uint64_t)(state ? kVestelAcSwing : 0xF)
+ << kVestelAcSwingOffset;
use_time_state = false;
}
// Return the Swing Roaming state of the A/C.
-bool IRVestelAC::getSwing() { return remote_state.swing == kVestelACSwing; }
+bool IRVestelAc::getSwing() {
+ return ((remote_state >> kVestelAcSwingOffset) & 0xF) == kVestelAcSwing;
+}
// Calculate the checksum for a given array.
// Args:
// state: The state to calculate the checksum over.
// Returns:
// The 8 bit checksum value.
-uint8_t IRVestelAC::calcChecksum(const uint64_t state) {
+uint8_t IRVestelAc::calcChecksum(const uint64_t state) {
// Just counts the set bits +1 on stream and take inverse after mask
uint8_t sum = 0;
- uint64_t temp_state = state & kVestelACCRCMask;
+ uint64_t temp_state = state & kVestelAcCRCMask;
for (; temp_state; temp_state >>= 1)
if (temp_state & 1) sum++;
sum += 2;
@@ -321,46 +378,48 @@ uint8_t IRVestelAC::calcChecksum(const uint64_t state) {
// state: The state to verify the checksum of.
// Returns:
// A boolean.
-bool IRVestelAC::validChecksum(const uint64_t state) {
- return (((state >> 12) & 0xFF) == calcChecksum(state));
+bool IRVestelAc::validChecksum(const uint64_t state) {
+ return (((state >> kVestelAcChecksumOffset) & 0xFF) == calcChecksum(state));
}
// Calculate & set the checksum for the current internal state of the remote.
-void IRVestelAC::checksum() {
+void IRVestelAc::checksum() {
// Stored the checksum value in the last byte.
- remote_state.CRC = calcChecksum(remote_state.rawCode);
- remote_time_state.CRC = calcChecksum(remote_time_state.rawCode);
+ remote_state &= ~((uint64_t)0xFF << kVestelAcChecksumOffset);
+ remote_state |= (uint64_t)calcChecksum(remote_state)
+ << kVestelAcChecksumOffset;
+
+ remote_time_state &= ~((uint64_t)0xFF << kVestelAcChecksumOffset);
+ remote_time_state |= (uint64_t)calcChecksum(remote_time_state)
+ << kVestelAcChecksumOffset;
}
-bool IRVestelAC::isTimeCommand() {
- return (remote_state.power == 0x00 || use_time_state);
+bool IRVestelAc::isTimeCommand() {
+ return (remote_state >> kVestelAcPowerOffset == 0x00 || use_time_state);
}
// Convert the internal state into a human readable string.
#ifdef ARDUINO
-String IRVestelAC::toString() {
+String IRVestelAc::toString() {
String result = "";
#else
-std::string IRVestelAC::toString() {
+std::string IRVestelAc::toString() {
std::string result = "";
#endif // ARDUINO
if (isTimeCommand()) {
result += "Time: " + IRHaierAC::timeToString(getTime());
result += ", Timer: ";
- result += remote_time_state.t_timer_mode
- ? IRHaierAC::timeToString(getTimer())
- : "Off";
+ result += isTimerActive() ? IRHaierAC::timeToString(getTimer()) : "Off";
result += ", On Timer: ";
- result += (remote_time_state.t_on_active && !remote_time_state.t_timer_mode)
+ result += (isOnTimerActive() && !isTimerActive())
? IRHaierAC::timeToString(getOnTimer())
: "Off";
result += ", Off Timer: ";
- result += remote_time_state.t_off_active
- ? IRHaierAC::timeToString(getOffTimer())
- : "Off";
+ result +=
+ isOffTimerActive() ? IRHaierAC::timeToString(getOffTimer()) : "Off";
return result;
}
// Not a time command, it's a normal command.
@@ -368,19 +427,19 @@ std::string IRVestelAC::toString() {
result += (getPower() ? "On" : "Off");
result += ", Mode: " + uint64ToString(getMode());
switch (getMode()) {
- case kVestelACAuto:
+ case kVestelAcAuto:
result += " (AUTO)";
break;
- case kVestelACCool:
+ case kVestelAcCool:
result += " (COOL)";
break;
- case kVestelACHeat:
+ case kVestelAcHeat:
result += " (HEAT)";
break;
- case kVestelACDry:
+ case kVestelAcDry:
result += " (DRY)";
break;
- case kVestelACFan:
+ case kVestelAcFan:
result += " (FAN)";
break;
default:
@@ -389,22 +448,22 @@ std::string IRVestelAC::toString() {
result += ", Temp: " + uint64ToString(getTemp()) + "C";
result += ", Fan: " + uint64ToString(getFan());
switch (getFan()) {
- case kVestelACFanAuto:
+ case kVestelAcFanAuto:
result += " (AUTO)";
break;
- case kVestelACFanLow:
+ case kVestelAcFanLow:
result += " (LOW)";
break;
- case kVestelACFanMed:
+ case kVestelAcFanMed:
result += " (MEDIUM)";
break;
- case kVestelACFanHigh:
+ case kVestelAcFanHigh:
result += " (HIGH)";
break;
- case kVestelACFanAutoCool:
+ case kVestelAcFanAutoCool:
result += " (AUTO COOL)";
break;
- case kVestelACFanAutoHot:
+ case kVestelAcFanAutoHot:
result += " (AUTO HOT)";
break;
default:
@@ -433,13 +492,13 @@ std::string IRVestelAC::toString() {
//
// Status: Alpha / Needs testing against a real device.
//
-bool IRrecv::decodeVestelAC(decode_results* results, uint16_t nbits,
+bool IRrecv::decodeVestelAc(decode_results* results, uint16_t nbits,
bool strict) {
if (nbits % 8 != 0) // nbits has to be a multiple of nr. of bits in a byte.
return false;
if (strict)
- if (nbits != kVestelACBits)
+ if (nbits != kVestelAcBits)
return false; // Not strictly a Vestel AC message.
uint64_t data = 0;
@@ -449,25 +508,25 @@ bool IRrecv::decodeVestelAC(decode_results* results, uint16_t nbits,
return false; // We can't possibly capture a Vestel packet that big.
// Header
- if (!matchMark(results->rawbuf[offset++], kVestelACHdrMark)) return false;
- if (!matchSpace(results->rawbuf[offset++], kVestelACHdrSpace)) return false;
+ if (!matchMark(results->rawbuf[offset++], kVestelAcHdrMark)) return false;
+ if (!matchSpace(results->rawbuf[offset++], kVestelAcHdrSpace)) return false;
// Data (Normal)
match_result_t data_result =
- matchData(&(results->rawbuf[offset]), nbits, kVestelACBitMark,
- kVestelACOneSpace, kVestelACBitMark, kVestelACZeroSpace,
- kVestelACTolerance, kMarkExcess, false);
+ matchData(&(results->rawbuf[offset]), nbits, kVestelAcBitMark,
+ kVestelAcOneSpace, kVestelAcBitMark, kVestelAcZeroSpace,
+ kVestelAcTolerance, kMarkExcess, false);
if (data_result.success == false) return false;
offset += data_result.used;
data = data_result.data;
// Footer
- if (!matchMark(results->rawbuf[offset++], kVestelACBitMark)) return false;
+ if (!matchMark(results->rawbuf[offset++], kVestelAcBitMark)) return false;
// Compliance
if (strict)
- if (!IRVestelAC::validChecksum(data_result.data)) return false;
+ if (!IRVestelAc::validChecksum(data_result.data)) return false;
// Success
results->decode_type = VESTEL_AC;
diff --git a/lib/IRremoteESP8266/src/ir_Vestel.h b/lib/IRremoteESP8266/src/ir_Vestel.h
index b8a8872..5c93ead 100644
--- a/lib/IRremoteESP8266/src/ir_Vestel.h
+++ b/lib/IRremoteESP8266/src/ir_Vestel.h
@@ -1,5 +1,6 @@
// Copyright 2018 Erdem U. Altinyurt
-// (Used Midea.h as template)
+// Copyright 2019 David Conran
+
#ifndef IR_VESTEL_H_
#define IR_VESTEL_H_
@@ -21,87 +22,88 @@
// Vestel added by Erdem U. Altinyurt
+// Structure of a Command message (56 bits)
+// Signature: 12 bits. e.g. 0x201
+// Checksum: 8 bits
+// Swing: 4 bits. (auto 0xA, stop 0xF)
+// turbo_sleep_normal: 4bits. (normal 0x1, sleep 0x3, turbo 0x7)
+// Unused: 8 bits. (0x00)
+// Temperature: 4 bits. (Celcius, but offset by -16 degrees. e.g. 0x0 = 16C)
+// Fan Speed: 4 bits (auto 0x1, low 0x5, mid 0x9, high 0xB, 0xD auto hot,
+// 0xC auto cool)
+// Mode: 3 bits. (auto 0x0, cold 0x1, dry 0x2, fan 0x3, hot 0x4)
+// unknown/unused: 6 bits.
+// Ion flag: 1 bit.
+// unknown/unused: 1 bit.
+// Power/message type: 4 bits. (on 0xF, off 0xC, 0x0 == Timer mesage)
+//
+// Structure of a Time(r) message (56 bits)
+// Signature: 12 bits. e.g. 0x201
+// Checksum: 8 bits
+// Off Minutes: 3 bits. (Stored in 10 min increments. eg. xx:20 is 0x2)
+// Off Hours: 5 bits. (0x17 == 11PM / 23:00)
+// On Minutes: 3 bits. (Stored in 10 min increments. eg. xx:20 is 0x2)
+// On Hours: 5 bits. (0x9 == 9AM / 09:00)
+// Clock Hours: 5 bits.
+// On Timer flag: 1 bit.
+// Off Timer flag: 1 bit.
+// Timer mode flag: 1 bit. (Off after X many hours/mins, not at clock time.)
+// Clock Minutes: 8 bits. (0-59)
+// Power/message type: 4 bits. (0x0 == Timer mesage, else see Comman message)
+
// Constants
-const uint16_t kVestelACHdrMark = 3110;
-const uint16_t kVestelACHdrSpace = 9066;
-const uint16_t kVestelACBitMark = 520;
-const uint16_t kVestelACOneSpace = 1535;
-const uint16_t kVestelACZeroSpace = 480;
-const uint16_t kVestelACTolerance = 30;
+const uint16_t kVestelAcHdrMark = 3110;
+const uint16_t kVestelAcHdrSpace = 9066;
+const uint16_t kVestelAcBitMark = 520;
+const uint16_t kVestelAcOneSpace = 1535;
+const uint16_t kVestelAcZeroSpace = 480;
+const uint16_t kVestelAcTolerance = 30;
-const uint8_t kVestelACMinTempH = 16;
-const uint8_t kVestelACMinTempC = 18;
-const uint8_t kVestelACMaxTemp = 30;
+const uint8_t kVestelAcMinTempH = 16;
+const uint8_t kVestelAcMinTempC = 18;
+const uint8_t kVestelAcMaxTemp = 30;
-const uint64_t kVestelACCRCMask = 0xFFFFFFFFFFF00000;
+const uint64_t kVestelAcCRCMask = 0xFFFFFFFFFFF00000;
-const uint8_t kVestelACAuto = 0;
-const uint8_t kVestelACCool = 1;
-const uint8_t kVestelACDry = 2;
-const uint8_t kVestelACFan = 3;
-const uint8_t kVestelACHeat = 4;
+const uint8_t kVestelAcAuto = 0;
+const uint8_t kVestelAcCool = 1;
+const uint8_t kVestelAcDry = 2;
+const uint8_t kVestelAcFan = 3;
+const uint8_t kVestelAcHeat = 4;
-const uint8_t kVestelACFanAuto = 1;
-const uint8_t kVestelACFanLow = 5;
-const uint8_t kVestelACFanMed = 9;
-const uint8_t kVestelACFanHigh = 0xB;
-const uint8_t kVestelACFanAutoCool = 0xC;
-const uint8_t kVestelACFanAutoHot = 0xD;
+const uint8_t kVestelAcFanAuto = 1;
+const uint8_t kVestelAcFanLow = 5;
+const uint8_t kVestelAcFanMed = 9;
+const uint8_t kVestelAcFanHigh = 0xB;
+const uint8_t kVestelAcFanAutoCool = 0xC;
+const uint8_t kVestelAcFanAutoHot = 0xD;
-const uint8_t kVestelACNormal = 1;
-const uint8_t kVestelACSleep = 3;
-const uint8_t kVestelACTurbo = 7;
-const uint8_t kVestelACIon = 4;
-const uint8_t kVestelACSwing = 0xA;
+const uint8_t kVestelAcNormal = 1;
+const uint8_t kVestelAcSleep = 3;
+const uint8_t kVestelAcTurbo = 7;
+const uint8_t kVestelAcIon = 4;
+const uint8_t kVestelAcSwing = 0xA;
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpacked-bitfield-compat"
-union VestelACState {
- // Remotes Command Stack
- struct {
- uint16_t footer : 12; // 0x201 footer
- uint8_t CRC : 8;
- uint8_t swing : 4; // auto 0xA, stop 0xF
- uint8_t turbo_sleep_normal : 4; // normal 0x1, sleep 0x3, turbo 0x7
- uint8_t zero : 8; // 0x00
- uint8_t temp : 4; // temp-16 degree Celcius
- uint8_t fan : 4; // auto 0x1, low 0x5, mid 0x9, high 0xB, 0xD auto hot, 0xC
- // auto cool
- uint8_t mode : 4; // auto 0x0, cold 0x1, dry 0x2, fan 0x3, hot 0x4
- uint8_t ion : 4; // on 0x4, off 0x0
- uint8_t power : 4; // on 0xF, off 0xC
- uint8_t not_used : 8;
- } __attribute__((packed)); // avoids padding.
+const uint8_t kVestelAcChecksumOffset = 12;
+const uint8_t kVestelAcSwingOffset = 20;
+const uint8_t kVestelAcTurboSleepOffset = 24;
+const uint8_t kVestelAcTempOffset = 36;
+const uint8_t kVestelAcFanOffset = 40;
+const uint8_t kVestelAcModeOffset = 44;
+const uint8_t kVestelAcIonOffset = 50;
+const uint8_t kVestelAcPowerOffset = 52;
+const uint8_t kVestelAcOffTimeOffset = 20;
+const uint8_t kVestelAcOnTimeOffset = 28;
+const uint8_t kVestelAcHourOffset = 36; // 5 bits
+const uint8_t kVestelAcOnTimerFlagOffset = kVestelAcHourOffset + 5;
+const uint8_t kVestelAcOffTimerFlagOffset = kVestelAcHourOffset + 6;
+const uint8_t kVestelAcTimerFlagOffset = kVestelAcHourOffset + 7;
+const uint8_t kVestelAcMinuteOffset = 44;
- uint64_t rawCode;
- // Remotes Timer Stack for programming AC unit for turn of after some time or
- // self wakeup - turn off at defined time. There are no timer functions
- // implemented.
- // Here is the stack only for decoding and reverse enginering purposes.
- struct {
- uint16_t t_footer : 12; // 0x201 footer
- uint8_t t_CRC : 8;
- // timer regs has 0x18 hour mask & 0x3=Minute mask minutes are divided to 10
- // format. Need to multiply with 10 Examples: 0x01= xx:10 and 0x08 = 01:00,
- // 0x03= 00:30 0x08=01:00 0x10=02:00 0x44=08:40
- uint8_t t_turnOffMinute : 3; // off minute/10
- uint8_t t_turnOffHour : 5;
- uint8_t t_turnOnMinute : 3; // on minute/10
- uint8_t t_turnOnHour : 5;
- uint8_t t_hour : 5; // actual time hour
- uint8_t t_on_active : 1;
- uint8_t t_off_active : 1;
- uint8_t t_timer_mode : 1; // For timer operation, also need t_on_active bit
- uint8_t t_minute : 8; // actual time minute
- uint16_t t_not_used : 16; // 00
- } __attribute__((packed)); // avoids padding.
-};
-#pragma GCC diagnostic pop
-
-class IRVestelAC {
+class IRVestelAc {
public:
- explicit IRVestelAC(uint16_t pin);
+ explicit IRVestelAc(uint16_t pin);
void stateReset();
#if SEND_VESTEL_AC
@@ -140,20 +142,24 @@ class IRVestelAC {
void setIon(const bool state);
bool getIon(void);
bool isTimeCommand(void);
+ bool isOnTimerActive(void);
+ void setOnTimerActive(const bool on);
+ bool isOffTimerActive(void);
+ void setOffTimerActive(const bool on);
+ bool isTimerActive(void);
+ void setTimerActive(const bool on);
+ static uint8_t calcChecksum(const uint64_t state);
#ifdef ARDUINO
String toString();
#else
std::string toString();
#endif
-#ifndef UNIT_TEST
-// private:
-#endif
- VestelACState remote_state;
- VestelACState remote_time_state;
- bool use_time_state = false;
+ private:
+ uint64_t remote_state;
+ uint64_t remote_time_state;
+ bool use_time_state;
void checksum();
- static uint8_t calcChecksum(const uint64_t state);
IRsend _irsend;
};
diff --git a/lib/IRremoteESP8266/test/IRsend_test.cpp b/lib/IRremoteESP8266/test/IRsend_test.cpp
index 3536399..03a59fc 100644
--- a/lib/IRremoteESP8266/test/IRsend_test.cpp
+++ b/lib/IRremoteESP8266/test/IRsend_test.cpp
@@ -1,7 +1,8 @@
-// Copyright 2017 David Conran
+// Copyright 2017,2019 David Conran
#include "IRsend_test.h"
#include "IRsend.h"
+#include "IRutils.h"
#include "gtest/gtest.h"
// Tests sendData().
@@ -288,3 +289,310 @@ TEST(TestLowLevelSend, SpaceNoModulation) {
irsend.space(1000);
EXPECT_EQ("[Off]1000usecs", irsend.low_level_sequence);
}
+
+// Test expected to work/produce a message for irsend:send()
+TEST(TestSend, GenericSimpleSendMethod) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ irsend.begin();
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(AIWA_RC_T501, 0x1234, kAiwaRcT501Bits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(AIWA_RC_T501, irsend.capture.decode_type);
+ EXPECT_EQ(kAiwaRcT501Bits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(CARRIER_AC, 0x1234, kCarrierAcBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(CARRIER_AC, irsend.capture.decode_type);
+ EXPECT_EQ(kCarrierAcBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(COOLIX, 0x1234, kCoolixBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(COOLIX, irsend.capture.decode_type);
+ EXPECT_EQ(kCoolixBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(DENON, 0x1234, kDenonBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(DENON, irsend.capture.decode_type);
+ EXPECT_EQ(kDenonBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(DISH, 0x1234, kDishBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(DISH, irsend.capture.decode_type);
+ EXPECT_EQ(kDishBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(GICABLE, 0x1234, kGicableBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(GICABLE, irsend.capture.decode_type);
+ EXPECT_EQ(kGicableBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(GREE, 0x0009205000200050, kGreeBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(GREE, irsend.capture.decode_type);
+ EXPECT_EQ(kGreeBits, irsend.capture.bits);
+ // No simple value test for gree as it decodes to an Array.
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(JVC, 0x1234, kJvcBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(JVC, irsend.capture.decode_type);
+ EXPECT_EQ(kJvcBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(LASERTAG, 0x123, kLasertagBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(LASERTAG, irsend.capture.decode_type);
+ EXPECT_EQ(kLasertagBits, irsend.capture.bits);
+ EXPECT_EQ(0x123, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(LG, 0x700992, kLgBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(LG, irsend.capture.decode_type);
+ EXPECT_EQ(kLgBits, irsend.capture.bits);
+ EXPECT_EQ(0x700992, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(LG, 0x700992, kLg32Bits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(LG, irsend.capture.decode_type);
+ EXPECT_EQ(kLg32Bits, irsend.capture.bits);
+ EXPECT_EQ(0x700992, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(LG2, 0x880094D, kLgBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(LG2, irsend.capture.decode_type);
+ EXPECT_EQ(kLgBits, irsend.capture.bits);
+ EXPECT_EQ(0x880094D, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(LUTRON, 0x1234, kLutronBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(LUTRON, irsend.capture.decode_type);
+ EXPECT_EQ(kLutronBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(MAGIQUEST, 0x560F40020455, kMagiquestBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(MAGIQUEST, irsend.capture.decode_type);
+ EXPECT_EQ(kMagiquestBits, irsend.capture.bits);
+ EXPECT_EQ(0x560F40020455, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(MIDEA, 0xA18263FFFF6E, kMideaBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(MIDEA, irsend.capture.decode_type);
+ EXPECT_EQ(kMideaBits, irsend.capture.bits);
+ EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(MITSUBISHI, 0x1234, kMitsubishiBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(MITSUBISHI, irsend.capture.decode_type);
+ EXPECT_EQ(kMitsubishiBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(MITSUBISHI2, 0x1234, kMitsubishiBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(MITSUBISHI2, irsend.capture.decode_type);
+ EXPECT_EQ(kMitsubishiBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(NIKAI, 0x1234, kNikaiBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(NIKAI, irsend.capture.decode_type);
+ EXPECT_EQ(kNikaiBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(NEC, 0x4BB640BF, kNECBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(NEC, irsend.capture.decode_type);
+ EXPECT_EQ(kNECBits, irsend.capture.bits);
+ EXPECT_EQ(0x4BB640BF, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(NEC_LIKE, 0x12345678, kNECBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(NEC_LIKE, irsend.capture.decode_type);
+ EXPECT_EQ(kNECBits, irsend.capture.bits);
+ EXPECT_EQ(0x12345678, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(PANASONIC, 0x40040190ED7C, kPanasonicBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
+ EXPECT_EQ(kPanasonicBits, irsend.capture.bits);
+ EXPECT_EQ(0x40040190ED7C, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(PIONEER, 0x659A05FAF50AC53A, kPioneerBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(PIONEER, irsend.capture.decode_type);
+ EXPECT_EQ(kPioneerBits, irsend.capture.bits);
+ EXPECT_EQ(0x659A05FAF50AC53A, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(RC5, 0x175, kRC5Bits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(RC5, irsend.capture.decode_type);
+ EXPECT_EQ(kRC5Bits, irsend.capture.bits);
+ EXPECT_EQ(0x175, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(RC6, 0xC800F740C, kRC6_36Bits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(RC6, irsend.capture.decode_type);
+ EXPECT_EQ(kRC6_36Bits, irsend.capture.bits);
+ EXPECT_EQ(0xC800F740C, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(RCMM, 0x1234, kRCMMBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(RCMM, irsend.capture.decode_type);
+ EXPECT_EQ(kRCMMBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(SAMSUNG, 0xE0E09966, kSamsungBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(SAMSUNG, irsend.capture.decode_type);
+ EXPECT_EQ(kSamsungBits, irsend.capture.bits);
+ EXPECT_EQ(0xE0E09966, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(SAMSUNG36, 0x1234, kSamsung36Bits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(SAMSUNG36, irsend.capture.decode_type);
+ EXPECT_EQ(kSamsung36Bits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(SANYO_LC7461, 0x2468DCB56A9, kSanyoLC7461Bits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(SANYO_LC7461, irsend.capture.decode_type);
+ EXPECT_EQ(kSanyoLC7461Bits, irsend.capture.bits);
+ EXPECT_EQ(0x2468DCB56A9, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(SHARP, 0x7266, kSharpBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(SHARP, irsend.capture.decode_type);
+ EXPECT_EQ(kSharpBits, irsend.capture.bits);
+ EXPECT_EQ(0x7266, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(SHERWOOD, 0x4BB640BF, kSherwoodBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(NEC, irsend.capture.decode_type);
+ EXPECT_EQ(kSherwoodBits, irsend.capture.bits);
+ EXPECT_EQ(0x4BB640BF, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(SONY, 0x1234, kSony20Bits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(SONY, irsend.capture.decode_type);
+ EXPECT_EQ(kSony20Bits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(TECO, 0x1234, kTecoBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(TECO, irsend.capture.decode_type);
+ EXPECT_EQ(kTecoBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(VESTEL_AC, 0xF4410001FF1201, kVestelAcBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
+ EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
+ EXPECT_EQ(0xF4410001FF1201, irsend.capture.value);
+
+ irsend.reset();
+ ASSERT_TRUE(irsend.send(WHYNTER, 0x1234, kWhynterBits));
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(WHYNTER, irsend.capture.decode_type);
+ EXPECT_EQ(kWhynterBits, irsend.capture.bits);
+ EXPECT_EQ(0x1234, irsend.capture.value);
+}
+
+// Test some expected types to NOT work/produce a message via irsend:send()
+TEST(TestSend, GenericSimpleSendMethodFailure) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ irsend.begin();
+
+ // Check nothing is sent for unexpected protocols
+ irsend.reset();
+ ASSERT_FALSE(irsend.send(KELVINATOR, 0x1234, kKelvinatorBits));
+ irsend.makeDecodeResult();
+ ASSERT_FALSE(irrecv.decode(&irsend.capture));
+
+ // For every A/C protocol which decodes to having a state[].
+ for (int i = 0; i < 200; i++) {
+ if (hasACState((decode_type_t)i) && i != GREE) { // Gree is an exception.
+ // Check it fails.
+ ASSERT_FALSE(irsend.send((decode_type_t)i, 0, 0));
+ }
+ }
+
+ // Test some other special cases.
+ ASSERT_FALSE(irsend.send(UNKNOWN, 0, 0));
+ ASSERT_FALSE(irsend.send(UNUSED, 0, 0));
+ ASSERT_FALSE(irsend.send(RAW, 0, 0));
+ ASSERT_FALSE(irsend.send(PRONTO, 0, 0));
+ ASSERT_FALSE(irsend.send(GLOBALCACHE, 0, 0));
+}
diff --git a/lib/IRremoteESP8266/test/Makefile b/lib/IRremoteESP8266/test/Makefile
index c684b5e..5787dc5 100644
--- a/lib/IRremoteESP8266/test/Makefile
+++ b/lib/IRremoteESP8266/test/Makefile
@@ -36,7 +36,7 @@ TESTS = IRutils_test IRsend_test ir_NEC_test ir_GlobalCache_test \
ir_Toshiba_test ir_Midea_test ir_Magiquest_test ir_Lasertag_test \
ir_Carrier_test ir_Haier_test ir_Hitachi_test ir_GICable_test \
ir_Whirlpool_test ir_Lutron_test ir_Electra_test ir_Pioneer_test \
- ir_MWM_test ir_Vestel_test
+ ir_MWM_test ir_Vestel_test ir_Teco_test ir_Tcl_test
# All Google Test headers. Usually you shouldn't change this
# definition.
@@ -80,7 +80,7 @@ PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.o \
ir_Kelvinator.o ir_Daikin.o ir_Gree.o ir_Pronto.o ir_Nikai.o ir_Toshiba.o \
ir_Midea.o ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o \
ir_Hitachi.o ir_GICable.o ir_Whirlpool.o ir_Lutron.o ir_Electra.o \
- ir_Pioneer.o ir_MWM.o ir_Vestel.o
+ ir_Pioneer.o ir_MWM.o ir_Vestel.o ir_Teco.o ir_Tcl.o
# All the IR Protocol header files.
PROTOCOLS_H = $(USER_DIR)/ir_Argo.h \
@@ -100,7 +100,9 @@ PROTOCOLS_H = $(USER_DIR)/ir_Argo.h \
$(USER_DIR)/ir_LG.h \
$(USER_DIR)/ir_Panasonic.h \
$(USER_DIR)/ir_Whirlpool.h \
- $(USER_DIR)/ir_Vestel.h
+ $(USER_DIR)/ir_Vestel.h \
+ $(USER_DIR)/ir_Tcl.h \
+ $(USER_DIR)/ir_Teco.h
# Common object files
COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o ir_GlobalCache.o \
$(PROTOCOLS) gtest_main.a
@@ -505,3 +507,21 @@ ir_Vestel_test.o : ir_Vestel_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
ir_Vestel_test : $(COMMON_OBJ) ir_Vestel_test.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
+
+ir_Teco.o : $(USER_DIR)/ir_Teco.cpp $(COMMON_DEPS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Teco.cpp
+
+ir_Teco_test.o : ir_Teco_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -I$(USER_DIR) -c ir_Teco_test.cpp
+
+ir_Teco_test : $(COMMON_OBJ) ir_Teco_test.o
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
+
+ir_Tcl.o : $(USER_DIR)/ir_Tcl.cpp $(COMMON_DEPS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Tcl.cpp
+
+ir_Tcl_test.o : ir_Tcl_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -I$(USER_DIR) -c ir_Tcl_test.cpp
+
+ir_Tcl_test : $(COMMON_OBJ) ir_Tcl_test.o
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
diff --git a/lib/IRremoteESP8266/test/ir_Coolix_test.cpp b/lib/IRremoteESP8266/test/ir_Coolix_test.cpp
index 86cbba5..537a64e 100644
--- a/lib/IRremoteESP8266/test/ir_Coolix_test.cpp
+++ b/lib/IRremoteESP8266/test/ir_Coolix_test.cpp
@@ -15,6 +15,14 @@ TEST(TestSendCoolix, SendDataOnly) {
irsend.reset();
irsend.sendCOOLIX(0x0);
EXPECT_EQ(
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
+ "m560s5040"
"m4480s4480"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
@@ -28,6 +36,14 @@ TEST(TestSendCoolix, SendDataOnly) {
irsend.reset();
irsend.sendCOOLIX(0xAA55AA);
EXPECT_EQ(
+ "m4480s4480"
+ "m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
+ "m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
+ "m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
+ "m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
+ "m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
+ "m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
+ "m560s5040"
"m4480s4480"
"m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560"
"m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680"
@@ -41,6 +57,14 @@ TEST(TestSendCoolix, SendDataOnly) {
irsend.reset();
irsend.sendCOOLIX(0xFFFFFF);
EXPECT_EQ(
+ "m4480s4480"
+ "m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s5040"
"m4480s4480"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
@@ -114,6 +138,10 @@ TEST(TestSendCoolix, SendUnusualSize) {
irsend.reset();
irsend.sendCOOLIX(0x0, 8);
EXPECT_EQ(
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
+ "m560s5040"
"m4480s4480"
"m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
"m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680m560s1680"
@@ -123,6 +151,24 @@ TEST(TestSendCoolix, SendUnusualSize) {
irsend.reset();
irsend.sendCOOLIX(0x1234567890ABCDEF, 64);
EXPECT_EQ(
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s1680m560s560m560s560m560s1680m560s560"
+ "m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560m560s1680"
+ "m560s560m560s560m560s1680m560s1680m560s560m560s1680m560s560m560s560"
+ "m560s1680m560s1680m560s560m560s560m560s1680m560s560m560s1680m560s1680"
+ "m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s1680m560s560"
+ "m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s560m560s1680"
+ "m560s560m560s1680m560s1680m560s1680m560s1680m560s560m560s560m560s560"
+ "m560s1680m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680"
+ "m560s1680m560s560m560s560m560s1680m560s560m560s560m560s560m560s560"
+ "m560s560m560s1680m560s1680m560s560m560s1680m560s1680m560s1680m560s1680"
+ "m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s1680"
+ "m560s560m560s1680m560s560m560s1680m560s560m560s1680m560s560m560s560"
+ "m560s1680m560s1680m560s560m560s560m560s1680m560s1680m560s560m560s1680"
+ "m560s560m560s560m560s1680m560s1680m560s560m560s560m560s1680m560s560"
+ "m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s1680m560s1680"
+ "m560s560m560s560m560s560m560s1680m560s560m560s560m560s560m560s560"
+ "m560s5040"
"m4480s4480"
"m560s560m560s560m560s560m560s1680m560s560m560s560m560s1680m560s560"
"m560s1680m560s1680m560s1680m560s560m560s1680m560s1680m560s560m560s1680"
@@ -411,7 +457,7 @@ TEST(TestCoolixACClass, HumanReadable) {
// Initial starting point.
EXPECT_EQ(
- "Power: On, Fan: 5 (AUTO), Mode: 2 (AUTO), Temp: 25C, "
+ "Power: On, Mode: 2 (AUTO), Fan: 5 (AUTO), Temp: 25C, "
"Zone Follow: Off, Sensor Temp: Ignored",
ircoolix.toString());
@@ -420,11 +466,11 @@ TEST(TestCoolixACClass, HumanReadable) {
ircoolix.setMode(kCoolixCool);
ircoolix.setFan(kCoolixFanMin);
EXPECT_EQ(
- "Power: On, Fan: 4 (MIN), Mode: 0 (COOL), Temp: 22C, "
+ "Power: On, Mode: 0 (COOL), Fan: 4 (MIN), Temp: 22C, "
"Zone Follow: On, Sensor Temp: 24C",
ircoolix.toString());
ircoolix.setSwing();
- EXPECT_EQ("Power: On, Fan: 3 (UNKNOWN), Swing: Toggle", ircoolix.toString());
+ EXPECT_EQ("Power: On, Swing: Toggle", ircoolix.toString());
ircoolix.setPower(false);
EXPECT_EQ("Power: Off", ircoolix.toString());
}
@@ -434,12 +480,12 @@ TEST(TestCoolixACClass, KnownExamples) {
ircoolix.setRaw(0b101100101011111111100100);
EXPECT_EQ(
- "Power: On, Fan: 5 (AUTO), Mode: 4 (FAN), Zone Follow: Off, "
+ "Power: On, Mode: 4 (FAN), Fan: 5 (AUTO), Zone Follow: Off, "
"Sensor Temp: Ignored",
ircoolix.toString());
ircoolix.setRaw(0b101100101001111100000000);
EXPECT_EQ(
- "Power: On, Fan: 4 (MIN), Mode: 0 (COOL), Temp: 17C, "
+ "Power: On, Mode: 0 (COOL), Fan: 4 (MIN), Temp: 17C, "
"Zone Follow: Off, Sensor Temp: Ignored",
ircoolix.toString());
}
@@ -449,7 +495,7 @@ TEST(TestCoolixACClass, Issue579FanAuto0) {
ircoolix.setRaw(0xB21F28);
EXPECT_EQ(
- "Power: On, Fan: 0 (AUTO0), Mode: 2 (AUTO), Temp: 20C, "
+ "Power: On, Mode: 2 (AUTO), Fan: 0 (AUTO0), Temp: 20C, "
"Zone Follow: Off, Sensor Temp: Ignored",
ircoolix.toString());
}
@@ -491,3 +537,56 @@ TEST(TestCoolixACClass, RealCaptureExample) {
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
}
+
+
+// Tests to debug/fix:
+// https://github.com/markszabo/IRremoteESP8266/issues/624
+TEST(TestCoolixACClass, Issue624HandleSpecialStatesBetter) {
+ IRCoolixAC ac(0);
+ ac.begin();
+ // Default
+ EXPECT_EQ(
+ "Power: On, Mode: 2 (AUTO), Fan: 5 (AUTO), Temp: 25C, Zone Follow: Off, "
+ "Sensor Temp: Ignored",
+ ac.toString());
+ EXPECT_EQ(0xB2BFC8, ac.getRaw());
+ // Change of settings.
+ ac.setPower(true);
+ ac.setTemp(24);
+ ac.setMode(kCoolixCool);
+ ac.setFan(kCoolixFanAuto);
+ EXPECT_EQ(
+ "Power: On, Mode: 0 (COOL), Fan: 5 (AUTO), Temp: 24C, Zone Follow: Off, "
+ "Sensor Temp: Ignored",
+ ac.toString());
+ EXPECT_EQ(0xB2BF40, ac.getRaw());
+ // Turn the unit off.
+ ac.setPower(false);
+ EXPECT_EQ(
+ "Power: Off",
+ ac.toString());
+ EXPECT_EQ(kCoolixOff, ac.getRaw());
+ // Repeat change of settings.
+ ac.setPower(true);
+ ac.setTemp(24);
+ ac.setMode(kCoolixCool);
+ ac.setFan(kCoolixFanAuto);
+ EXPECT_EQ(
+ "Power: On, Mode: 0 (COOL), Fan: 5 (AUTO), Temp: 24C, Zone Follow: Off, "
+ "Sensor Temp: Ignored",
+ ac.toString());
+ EXPECT_EQ(0xB2BF40, ac.getRaw());
+
+ // Now test if we setRaw() a special state first.
+ ac.setRaw(kCoolixSwing);
+ // Repeat change of settings.
+ ac.setPower(true);
+ ac.setTemp(24);
+ ac.setMode(kCoolixCool);
+ ac.setFan(kCoolixFanAuto);
+ EXPECT_EQ(
+ "Power: On, Mode: 0 (COOL), Fan: 5 (AUTO), Temp: 24C, Zone Follow: Off, "
+ "Sensor Temp: Ignored",
+ ac.toString());
+ EXPECT_EQ(0xB2BF40, ac.getRaw());
+}
diff --git a/lib/IRremoteESP8266/test/ir_LG_test.cpp b/lib/IRremoteESP8266/test/ir_LG_test.cpp
index 8ab24a7..30ca07e 100644
--- a/lib/IRremoteESP8266/test/ir_LG_test.cpp
+++ b/lib/IRremoteESP8266/test/ir_LG_test.cpp
@@ -420,3 +420,54 @@ TEST(TestDecodeLG2, RealLG2Example) {
EXPECT_EQ(kLgBits, irsend.capture.bits);
EXPECT_EQ(0x880094D, irsend.capture.value);
}
+
+// Tests for issue reported in
+// https://github.com/markszabo/IRremoteESP8266/issues/620
+TEST(TestDecodeLG, Issue620) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ irsend.begin();
+
+ // Raw data as reported in initial comment of Issue #620
+ uint16_t rawData[59] = {
+ 8886, 4152,
+ 560, 1538, 532, 502, 532, 504, 530, 484, 558, 1536,
+ 508, 516, 558, 502, 532, 484, 558, 502, 532, 500,
+ 534, 508, 532, 502, 532, 1518, 558, 510, 532, 484,
+ 556, 486, 556, 510, 532, 1518, 558, 1560, 532, 1528,
+ 556, 504, 530, 506, 530, 1520, 558, 508, 534, 500,
+ 532, 512, 530, 484, 556, 1536, 532}; // LG 8808721
+ irsend.sendRaw(rawData, 59, 38000);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(LG, irsend.capture.decode_type);
+ EXPECT_EQ(28, irsend.capture.bits);
+ EXPECT_EQ(0x8808721, irsend.capture.value);
+ EXPECT_EQ(0x88, irsend.capture.address);
+ EXPECT_EQ(0x872, irsend.capture.command);
+
+ irsend.reset();
+
+ // Resend the same code as the report is a sent code doesn't decode
+ // to the same message code.
+ irsend.sendLG(0x8808721);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(LG, irsend.capture.decode_type);
+ EXPECT_EQ(28, irsend.capture.bits);
+ EXPECT_EQ(0x8808721, irsend.capture.value);
+ EXPECT_EQ(0x88, irsend.capture.address);
+ EXPECT_EQ(0x872, irsend.capture.command);
+ // The following seems to match the rawData above.
+ EXPECT_EQ(
+ "m8500s4250"
+ "m550s1600m550s550m550s550m550s550m550s1600"
+ "m550s550m550s550m550s550m550s550m550s550"
+ "m550s550m550s550m550s1600m550s550m550s550"
+ "m550s550m550s550m550s1600m550s1600m550s1600"
+ "m550s550m550s550m550s1600m550s550m550s550"
+ "m550s550m550s550m550s1600m550"
+ "s55550",
+ irsend.outputStr());
+}
+
diff --git a/lib/IRremoteESP8266/test/ir_Samsung_test.cpp b/lib/IRremoteESP8266/test/ir_Samsung_test.cpp
index 4c79803..390e86e 100644
--- a/lib/IRremoteESP8266/test/ir_Samsung_test.cpp
+++ b/lib/IRremoteESP8266/test/ir_Samsung_test.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 David Conran
+// Copyright 2017, 2018, 2019 David Conran
#include "ir_Samsung.h"
#include "IRrecv.h"
@@ -7,6 +7,13 @@
#include "IRsend_test.h"
#include "gtest/gtest.h"
+
+// General housekeeping
+TEST(TestSamsung, Housekeeping) {
+ ASSERT_EQ("SAMSUNG", typeToString(SAMSUNG));
+ ASSERT_FALSE(hasACState(SAMSUNG));
+}
+
// Tests for sendSAMSUNG().
// Test sending typical data only.
@@ -281,6 +288,12 @@ TEST(TestDecodeSamsung, FailToDecodeNonSamsungExample) {
ASSERT_FALSE(irrecv.decodeSAMSUNG(&irsend.capture, kSamsungBits, false));
}
+// General housekeeping
+TEST(TestSamsungAC, Housekeeping) {
+ ASSERT_EQ("SAMSUNG_AC", typeToString(SAMSUNG_AC));
+ ASSERT_TRUE(hasACState(SAMSUNG_AC));
+}
+
// Tests for sendSamsungAC().
// Test sending typical data only.
@@ -976,3 +989,133 @@ TEST(TestDecodeSamsungAC, Issue604DecodeExtended) {
"Beep: Off, Clean: Off, Quiet: Off",
samsung.toString());
}
+
+TEST(TestSendSamsung36, SendDataOnly) {
+ IRsendTest irsend(0);
+ irsend.begin();
+
+ irsend.reset();
+ irsend.sendSamsung36(0);
+ EXPECT_EQ(
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s560m560s560m560s560m560s560"
+ "m560s26880",
+ irsend.outputStr());
+ irsend.sendSamsung36(0x400E00FF);
+ EXPECT_EQ(
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s4480"
+ "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
+ "m560s1680m560s1680m560s1680m560s1680"
+ "m560s26880",
+ irsend.outputStr());
+ irsend.reset();
+}
+
+// General housekeeping
+TEST(TestSamsung36, Housekeeping) {
+ ASSERT_EQ("SAMSUNG36", typeToString(SAMSUNG36));
+ ASSERT_FALSE(hasACState(SAMSUNG36));
+}
+
+// Test sending with different repeats.
+TEST(TestSendSamsung36, SendWithRepeats) {
+ IRsendTest irsend(0);
+ irsend.begin();
+
+ irsend.reset();
+ irsend.sendSamsung36(0x400E00FF, kSamsung36Bits, 1); // 1 repeat.
+ EXPECT_EQ(
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s4480"
+ "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
+ "m560s1680m560s1680m560s1680m560s1680"
+ "m560s26880"
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s4480"
+ "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
+ "m560s1680m560s1680m560s1680m560s1680"
+ "m560s26880",
+ irsend.outputStr());
+ irsend.sendSamsung36(0x400E00FF, kSamsung36Bits, 2); // 2 repeats.
+ EXPECT_EQ(
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s4480"
+ "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
+ "m560s1680m560s1680m560s1680m560s1680"
+ "m560s26880"
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s4480"
+ "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
+ "m560s1680m560s1680m560s1680m560s1680"
+ "m560s26880"
+ "m4480s4480"
+ "m560s560m560s560m560s560m560s560m560s560m560s1680m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s560m560s560m560s560m560s560"
+ "m560s4480"
+ "m560s1680m560s1680m560s1680m560s560m560s560m560s560m560s560m560s560"
+ "m560s560m560s560m560s560m560s560m560s1680m560s1680m560s1680m560s1680"
+ "m560s1680m560s1680m560s1680m560s1680"
+ "m560s26880",
+ irsend.outputStr());
+}
+
+TEST(TestDecodeSamsung36, RealExample) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ irsend.begin();
+
+ irsend.reset();
+ uint16_t rawData[77] = {
+ 4542, 4438, 568, 432, 562, 436, 536, 462, 538, 460, 538, 460, 564, 1434,
+ 564, 434, 534, 464, 536, 462, 562, 436, 536, 464, 564, 432, 538, 462, 536,
+ 464, 534, 464, 564, 420, 566, 4414, 538, 1462, 566, 1432, 562, 1436, 536,
+ 462, 564, 436, 562, 436, 560, 436, 562, 436, 562, 436, 560, 438, 536, 462,
+ 562, 436, 562, 1436, 562, 1434, 536, 1462, 564, 1434, 562, 1436, 564,
+ 1436, 534, 1462, 534, 1464, 536}; // UNKNOWN E4CD1208
+
+ irsend.sendRaw(rawData, 77, 38000);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(SAMSUNG36, irsend.capture.decode_type);
+ EXPECT_EQ(kSamsung36Bits, irsend.capture.bits);
+ EXPECT_EQ(0x400E00FF, irsend.capture.value);
+ EXPECT_EQ(0xE00FF, irsend.capture.command);
+ EXPECT_EQ(0x400, irsend.capture.address);
+}
+
+TEST(TestDecodeSamsung36, SyntheticExample) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ irsend.begin();
+ irsend.reset();
+
+ irsend.sendSamsung36(0x400E00FF);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decodeSamsung36(&irsend.capture));
+ ASSERT_EQ(SAMSUNG36, irsend.capture.decode_type);
+ EXPECT_EQ(kSamsung36Bits, irsend.capture.bits);
+ EXPECT_EQ(0x400E00FF, irsend.capture.value);
+ EXPECT_EQ(0xE00FF, irsend.capture.command);
+ EXPECT_EQ(0x400, irsend.capture.address);
+}
diff --git a/lib/IRremoteESP8266/test/ir_Tcl_test.cpp b/lib/IRremoteESP8266/test/ir_Tcl_test.cpp
new file mode 100644
index 0000000..3d8bec3
--- /dev/null
+++ b/lib/IRremoteESP8266/test/ir_Tcl_test.cpp
@@ -0,0 +1,247 @@
+// Copyright 2019 David Conran
+
+#include "ir_Tcl.h"
+#include "IRrecv.h"
+#include "IRrecv_test.h"
+#include "IRsend.h"
+#include "IRsend_test.h"
+#include "gtest/gtest.h"
+
+// General housekeeping
+TEST(TestTcl112Ac, Housekeeping) {
+ ASSERT_EQ("TCL112AC", typeToString(TCL112AC));
+ ASSERT_TRUE(hasACState(TCL112AC));
+}
+
+// Tests for decodeTcl112Ac().
+
+// Decode a real Tcl112Ac A/C example from Issue #619
+TEST(TestDecodeTcl112Ac, DecodeRealExample) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ irsend.begin();
+
+ irsend.reset();
+ // Tcl112Ac A/C example from Issue #619 On.txt
+ uint16_t rawData[227] = {
+ 3030, 1658, 494, 1066, 494, 1068, 498, 320, 494,
+ 326, 498, 320, 494, 1068, 500, 320, 494, 332,
+ 494, 1068, 500, 1062, 496, 324, 492, 1044, 524,
+ 322, 492, 326, 498, 1062, 494, 1074, 494, 326,
+ 500, 1062, 496, 1066, 490, 328, 496, 322, 492,
+ 1070, 498, 322, 494, 332, 492, 1068, 498, 320,
+ 494, 326, 498, 320, 496, 324, 500, 320, 494,
+ 324, 490, 336, 500, 320, 496, 324, 490, 328,
+ 496, 322, 492, 328, 498, 322, 492, 326, 498,
+ 328, 496, 322, 492, 328, 498, 1064, 494, 326,
+ 498, 320, 494, 1066, 490, 330, 496, 330, 494,
+ 1066, 490, 1070, 498, 322, 492, 328, 498, 322,
+ 492, 326, 498, 322, 492, 332, 492, 1068, 498,
+ 1062, 494, 1066, 500, 318, 496, 324, 490, 328,
+ 496, 324, 492, 334, 490, 328, 496, 324, 492,
+ 328, 496, 322, 492, 328, 498, 320, 494, 1068,
+ 500, 326, 500, 320, 492, 326, 500, 320, 496,
+ 324, 500, 318, 496, 324, 490, 328, 496, 330,
+ 496, 324, 490, 328, 496, 324, 490, 328, 498,
+ 322, 492, 328, 498, 320, 492, 334, 492, 328,
+ 498, 322, 494, 326, 498, 320, 494, 324, 500,
+ 322, 492, 324, 490, 336, 498, 320, 494, 324,
+ 500, 320, 496, 324, 490, 328, 498, 322, 492,
+ 328, 496, 1070, 496, 1064, 492, 1070, 498, 322,
+ 494, 326, 500, 320, 494, 324, 500, 320, 494,
+ 324, 470}; // UNKNOWN CE60D6B9
+ uint8_t expectedState[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x07, 0x40, 0x00, 0x00, 0x00, 0x80, 0x03};
+
+ irsend.sendRaw(rawData, 227, 38000);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(TCL112AC, irsend.capture.decode_type);
+ EXPECT_EQ(kTcl112AcBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
+
+ IRTcl112Ac ac(0);
+ ac.setRaw(irsend.capture.state);
+ EXPECT_EQ("Power: On, Mode: 3 (COOL), Temp: 24C", ac.toString());
+}
+
+// Decode a synthetic Tcl112Ac A/C example from Issue #619
+TEST(TestDecodeTcl112Ac, DecodeSyntheticExample) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ irsend.begin();
+
+ irsend.reset();
+
+ uint8_t expectedState[kTcl112AcStateLength] = {0x23, 0xCB, 0x26, 0x01, 0x00,
+ 0x24, 0x03, 0x07, 0x40, 0x00,
+ 0x00, 0x00, 0x80, 0x03};
+
+ irsend.sendTcl112Ac(expectedState);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(TCL112AC, irsend.capture.decode_type);
+ EXPECT_EQ(kTcl112AcBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
+}
+
+TEST(TestTcl112AcClass, Temperature) {
+ const uint8_t temp16C[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xCB};
+ const uint8_t temp16point5C[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xEB};
+ const uint8_t temp19point5C[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x0C, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xE8};
+ const uint8_t temp31C[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBC};
+ IRTcl112Ac ac(0);
+ ac.setRaw(temp16C);
+ EXPECT_EQ("Power: On, Mode: 3 (COOL), Temp: 16C", ac.toString());
+ ac.setRaw(temp16point5C);
+ EXPECT_EQ("Power: On, Mode: 3 (COOL), Temp: 16.5C", ac.toString());
+ ac.setRaw(temp19point5C);
+ EXPECT_EQ("Power: On, Mode: 3 (COOL), Temp: 19.5C", ac.toString());
+ ac.setRaw(temp31C);
+ EXPECT_EQ("Power: On, Mode: 3 (COOL), Temp: 31C", ac.toString());
+
+ ac.setTemp(kTcl112AcTempMin);
+ EXPECT_EQ(kTcl112AcTempMin, ac.getTemp());
+
+ ac.setTemp(kTcl112AcTempMin + 1);
+ EXPECT_EQ(kTcl112AcTempMin + 1, ac.getTemp());
+
+ ac.setTemp(kTcl112AcTempMax);
+ EXPECT_EQ(kTcl112AcTempMax, ac.getTemp());
+
+ ac.setTemp(kTcl112AcTempMin - 1);
+ EXPECT_EQ(kTcl112AcTempMin, ac.getTemp());
+
+ ac.setTemp(kTcl112AcTempMax + 0.5);
+ EXPECT_EQ(kTcl112AcTempMax, ac.getTemp());
+
+ ac.setTemp(23);
+ EXPECT_EQ(23, ac.getTemp());
+
+ ac.setTemp(27.4);
+ EXPECT_EQ(27, ac.getTemp());
+
+ ac.setTemp(22.5);
+ EXPECT_EQ(22.5, ac.getTemp());
+
+ ac.setTemp(25.6);
+ EXPECT_EQ(25.5, ac.getTemp());
+
+ ac.setTemp(0);
+ EXPECT_EQ(kTcl112AcTempMin, ac.getTemp());
+
+ ac.setTemp(255);
+ EXPECT_EQ(kTcl112AcTempMax, ac.getTemp());
+}
+
+TEST(TestTcl112AcClass, OperatingMode) {
+ IRTcl112Ac ac(0);
+ ac.begin();
+
+ ac.setMode(kTcl112AcAuto);
+ EXPECT_EQ(kTcl112AcAuto, ac.getMode());
+
+ ac.setMode(kTcl112AcCool);
+ EXPECT_EQ(kTcl112AcCool, ac.getMode());
+
+ ac.setMode(kTcl112AcHeat);
+ EXPECT_EQ(kTcl112AcHeat, ac.getMode());
+
+ ac.setMode(kTcl112AcFan);
+ EXPECT_EQ(kTcl112AcFan, ac.getMode());
+
+ ac.setMode(kTcl112AcDry);
+ EXPECT_EQ(kTcl112AcDry, ac.getMode());
+
+ ac.setMode(kTcl112AcHeat - 1);
+ EXPECT_EQ(kTcl112AcAuto, ac.getMode());
+
+ ac.setMode(kTcl112AcCool);
+ EXPECT_EQ(kTcl112AcCool, ac.getMode());
+
+ ac.setMode(kTcl112AcAuto + 1);
+ EXPECT_EQ(kTcl112AcAuto, ac.getMode());
+
+ ac.setMode(kTcl112AcCool);
+ ac.setMode(255);
+ EXPECT_EQ(kTcl112AcAuto, ac.getMode());
+
+ ac.setMode(kTcl112AcCool);
+ ac.setMode(0);
+ EXPECT_EQ(kTcl112AcAuto, ac.getMode());
+
+ const uint8_t automode[] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x08,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x48};
+ ac.setRaw(automode);
+ EXPECT_EQ("Power: On, Mode: 8 (AUTO), Temp: 24C", ac.toString());
+}
+
+TEST(TestTcl112AcClass, Power) {
+ IRTcl112Ac ac(0);
+ ac.begin();
+
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+
+ ac.setPower(false);
+ EXPECT_EQ(false, ac.getPower());
+
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+
+ ac.off();
+ EXPECT_EQ(false, ac.getPower());
+
+ ac.on();
+ EXPECT_TRUE(ac.getPower());
+
+ const uint8_t on[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xCB};
+ ac.setRaw(on);
+ EXPECT_EQ("Power: On, Mode: 3 (COOL), Temp: 16C", ac.toString());
+
+ const uint8_t off[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x03,
+ 0x07, 0x40, 0x00, 0x00, 0x00, 0x80, 0xCB};
+ ac.setRaw(off);
+ EXPECT_EQ("Power: Off, Mode: 3 (COOL), Temp: 24C", ac.toString());
+}
+
+
+TEST(TestTcl112AcClass, Checksum) {
+ uint8_t temp16C[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xCB};
+ uint8_t temp31C[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBC};
+ IRTcl112Ac ac(0);
+ EXPECT_EQ(0xCB, ac.calcChecksum(temp16C));
+ ac.setRaw(temp16C);
+ EXPECT_EQ("Power: On, Mode: 3 (COOL), Temp: 16C", ac.toString());
+ ac.setRaw(temp31C);
+ EXPECT_EQ("Power: On, Mode: 3 (COOL), Temp: 31C", ac.toString());
+ EXPECT_EQ(0xBC, ac.calcChecksum(temp31C));
+
+ EXPECT_TRUE(IRTcl112Ac::validChecksum(temp16C));
+ EXPECT_TRUE(IRTcl112Ac::validChecksum(temp31C));
+ EXPECT_TRUE(ac.validChecksum(temp31C));
+ ac.setRaw(temp16C);
+ EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
+ ac.setTemp(31);
+ EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
+ EXPECT_EQ(0xBC, ac.calcChecksum(ac.getRaw()));
+}
diff --git a/lib/IRremoteESP8266/test/ir_Teco_test.cpp b/lib/IRremoteESP8266/test/ir_Teco_test.cpp
new file mode 100644
index 0000000..7e639e2
--- /dev/null
+++ b/lib/IRremoteESP8266/test/ir_Teco_test.cpp
@@ -0,0 +1,356 @@
+// Copyright 2019 David Conran
+
+#include "ir_Teco.h"
+#include "IRrecv.h"
+#include "IRrecv_test.h"
+#include "IRsend.h"
+#include "IRsend_test.h"
+#include "gtest/gtest.h"
+
+// General housekeeping
+TEST(TestTeco, Housekeeping) {
+ ASSERT_EQ("TECO", typeToString(TECO));
+ ASSERT_FALSE(hasACState(TECO)); // Uses uint64_t, not uint8_t*.
+}
+
+// Tests for sendTeco()
+
+// Test sending typical data only.
+TEST(TestSendTeco, SendDataOnly) {
+ IRsendTest irsend(0);
+ irsend.begin();
+
+ irsend.reset();
+ irsend.sendTeco(0x250002BC9);
+ EXPECT_EQ(
+ "m9000s4440"
+ "m620s1650m620s580m620s580m620s1650m620s580m620s580m620s1650m620s1650"
+ "m620s1650m620s1650m620s580m620s1650m620s580m620s1650m620s580m620s580"
+ "m620s580m620s580m620s580m620s580m620s580m620s580m620s580m620s580"
+ "m620s580m620s580m620s580m620s580m620s1650m620s580m620s1650m620s580"
+ "m620s580m620s1650m620s580"
+ "m620s1000000",
+ irsend.outputStr());
+}
+
+// Test sending typical data with repeats.
+TEST(TestSendTeco, SendWithRepeats) {
+ IRsendTest irsend(0);
+ irsend.begin();
+
+ irsend.reset();
+ irsend.sendTeco(0x250002BC9, kTecoBits, 2); // two repeats.
+ EXPECT_EQ(
+ "m9000s4440"
+ "m620s1650m620s580m620s580m620s1650m620s580m620s580m620s1650m620s1650"
+ "m620s1650m620s1650m620s580m620s1650m620s580m620s1650m620s580m620s580"
+ "m620s580m620s580m620s580m620s580m620s580m620s580m620s580m620s580"
+ "m620s580m620s580m620s580m620s580m620s1650m620s580m620s1650m620s580"
+ "m620s580m620s1650m620s580"
+ "m620s1000000"
+ "m9000s4440"
+ "m620s1650m620s580m620s580m620s1650m620s580m620s580m620s1650m620s1650"
+ "m620s1650m620s1650m620s580m620s1650m620s580m620s1650m620s580m620s580"
+ "m620s580m620s580m620s580m620s580m620s580m620s580m620s580m620s580"
+ "m620s580m620s580m620s580m620s580m620s1650m620s580m620s1650m620s580"
+ "m620s580m620s1650m620s580"
+ "m620s1000000"
+ "m9000s4440"
+ "m620s1650m620s580m620s580m620s1650m620s580m620s580m620s1650m620s1650"
+ "m620s1650m620s1650m620s580m620s1650m620s580m620s1650m620s580m620s580"
+ "m620s580m620s580m620s580m620s580m620s580m620s580m620s580m620s580"
+ "m620s580m620s580m620s580m620s580m620s1650m620s580m620s1650m620s580"
+ "m620s580m620s1650m620s580"
+ "m620s1000000",
+ irsend.outputStr());
+}
+
+
+// Tests for IRTeco class.
+
+TEST(TestTecoACClass, Power) {
+ IRTecoAc ac(0);
+ ac.begin();
+
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+
+ ac.setPower(false);
+ EXPECT_EQ(false, ac.getPower());
+
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+
+ ac.off();
+ EXPECT_EQ(false, ac.getPower());
+
+ ac.on();
+ EXPECT_TRUE(ac.getPower());
+}
+
+TEST(TestTecoACClass, OperatingMode) {
+ IRTecoAc ac(0);
+ ac.begin();
+
+ ac.setMode(kTecoAuto);
+ EXPECT_EQ(kTecoAuto, ac.getMode());
+
+ ac.setMode(kTecoCool);
+ EXPECT_EQ(kTecoCool, ac.getMode());
+
+ ac.setMode(kTecoHeat);
+ EXPECT_EQ(kTecoHeat, ac.getMode());
+
+ ac.setMode(kTecoFan);
+ EXPECT_EQ(kTecoFan, ac.getMode());
+
+ ac.setMode(kTecoDry);
+ EXPECT_EQ(kTecoDry, ac.getMode());
+
+ ac.setMode(kTecoAuto - 1);
+ EXPECT_EQ(kTecoAuto, ac.getMode());
+
+ ac.setMode(kTecoCool);
+ EXPECT_EQ(kTecoCool, ac.getMode());
+
+ ac.setMode(kTecoHeat + 1);
+ EXPECT_EQ(kTecoAuto, ac.getMode());
+
+ ac.setMode(255);
+ EXPECT_EQ(kTecoAuto, ac.getMode());
+}
+
+TEST(TestTecoACClass, Temperature) {
+ IRTecoAc ac(0);
+ ac.begin();
+
+ ac.setTemp(kTecoMinTemp);
+ EXPECT_EQ(kTecoMinTemp, ac.getTemp());
+
+ ac.setTemp(kTecoMinTemp + 1);
+ EXPECT_EQ(kTecoMinTemp + 1, ac.getTemp());
+
+ ac.setTemp(kTecoMaxTemp);
+ EXPECT_EQ(kTecoMaxTemp, ac.getTemp());
+
+ ac.setTemp(kTecoMinTemp - 1);
+ EXPECT_EQ(kTecoMinTemp, ac.getTemp());
+
+ ac.setTemp(kTecoMaxTemp + 1);
+ EXPECT_EQ(kTecoMaxTemp, ac.getTemp());
+
+ ac.setTemp(23);
+ EXPECT_EQ(23, ac.getTemp());
+
+ ac.setTemp(0);
+ EXPECT_EQ(kTecoMinTemp, ac.getTemp());
+
+ ac.setTemp(255);
+ EXPECT_EQ(kTecoMaxTemp, ac.getTemp());
+}
+
+TEST(TestTecoACClass, FanSpeed) {
+ IRTecoAc ac(0);
+ ac.begin();
+ ac.setFan(kTecoFanLow);
+
+ ac.setFan(kTecoFanAuto);
+ EXPECT_EQ(kTecoFanAuto, ac.getFan());
+
+ ac.setFan(kTecoFanLow);
+ EXPECT_EQ(kTecoFanLow, ac.getFan());
+ ac.setFan(kTecoFanMed);
+ EXPECT_EQ(kTecoFanMed, ac.getFan());
+ ac.setFan(kTecoFanHigh);
+ EXPECT_EQ(kTecoFanHigh, ac.getFan());
+
+ ac.setFan(kTecoFanHigh);
+ EXPECT_EQ(kTecoFanHigh, ac.getFan());
+}
+
+TEST(TestTecoACClass, Swing) {
+ IRTecoAc ac(0);
+ ac.begin();
+
+ ac.setSwing(true);
+ EXPECT_TRUE(ac.getSwing());
+
+ ac.setSwing(false);
+ EXPECT_EQ(false, ac.getSwing());
+
+ ac.setSwing(true);
+ EXPECT_TRUE(ac.getSwing());
+}
+
+TEST(TestTecoACClass, Sleep) {
+ IRTecoAc ac(0);
+ ac.begin();
+
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+
+ ac.setSleep(false);
+ EXPECT_EQ(false, ac.getSleep());
+
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+}
+
+TEST(TestTecoACClass, MessageConstuction) {
+ IRTecoAc ac(0);
+
+ EXPECT_EQ(
+ "Power: Off, Mode: 0 (AUTO), Temp: 16C, Fan: 0 (Auto), Sleep: Off, "
+ "Swing: Off",
+ ac.toString());
+ ac.setPower(true);
+ ac.setMode(kTecoCool);
+ ac.setTemp(21);
+ ac.setFan(kTecoFanHigh);
+ ac.setSwing(false);
+ EXPECT_EQ(
+ "Power: On, Mode: 1 (COOL), Temp: 21C, Fan: 3 (High), Sleep: Off, "
+ "Swing: Off",
+ ac.toString());
+ ac.setSwing(true);
+ EXPECT_EQ(
+ "Power: On, Mode: 1 (COOL), Temp: 21C, Fan: 3 (High), Sleep: Off, "
+ "Swing: On",
+ ac.toString());
+ ac.setSwing(false);
+ ac.setFan(kTecoFanLow);
+ ac.setSleep(true);
+ ac.setMode(kTecoHeat);
+ EXPECT_EQ(
+ "Power: On, Mode: 4 (HEAT), Temp: 21C, Fan: 1 (Low), Sleep: On, "
+ "Swing: Off",
+ ac.toString());
+ ac.setSleep(false);
+ EXPECT_EQ(
+ "Power: On, Mode: 4 (HEAT), Temp: 21C, Fan: 1 (Low), Sleep: Off, "
+ "Swing: Off",
+ ac.toString());
+ ac.setTemp(25);
+ EXPECT_EQ(
+ "Power: On, Mode: 4 (HEAT), Temp: 25C, Fan: 1 (Low), Sleep: Off, "
+ "Swing: Off",
+ ac.toString());
+}
+
+TEST(TestTecoACClass, ReconstructKnownMessage) {
+ IRTecoAc ac(0);
+
+ const uint64_t expected = 0x250002BC9;
+ ASSERT_FALSE(ac.getRaw() == expected);
+ ac.setPower(true);
+ ac.setMode(kTecoCool);
+ ac.setTemp(27);
+ ac.setFan(kTecoFanAuto);
+ ac.setSleep(true);
+ ac.setSwing(true);
+ EXPECT_EQ(expected, ac.getRaw());
+ EXPECT_EQ(
+ "Power: On, Mode: 1 (COOL), Temp: 27C, Fan: 0 (Auto), Sleep: On, "
+ "Swing: On",
+ ac.toString());
+}
+
+// Tests for decodeTeco().
+
+// Decode normal "synthetic" messages.
+TEST(TestDecodeTeco, NormalDecodeWithStrict) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ irsend.begin();
+
+ // With the specific decoder.
+ uint64_t expectedState = kTecoReset;
+ irsend.reset();
+ irsend.sendTeco(expectedState);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decodeTeco(&irsend.capture, kTecoBits, true));
+ EXPECT_EQ(TECO, irsend.capture.decode_type);
+ EXPECT_EQ(kTecoBits, irsend.capture.bits);
+ EXPECT_FALSE(irsend.capture.repeat);
+ EXPECT_EQ(expectedState, irsend.capture.value);
+ EXPECT_EQ(0, irsend.capture.address);
+ EXPECT_EQ(0, irsend.capture.command);
+
+ // With the all the decoders.
+ irsend.reset();
+ irsend.sendTeco(expectedState);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(TECO, irsend.capture.decode_type);
+ EXPECT_EQ(kTecoBits, irsend.capture.bits);
+ EXPECT_FALSE(irsend.capture.repeat);
+ EXPECT_EQ(expectedState, irsend.capture.value);
+ EXPECT_EQ(0, irsend.capture.address);
+ EXPECT_EQ(0, irsend.capture.command);
+
+ IRTecoAc ac(0);
+ ac.begin();
+ ac.setRaw(irsend.capture.value);
+ EXPECT_EQ(
+ "Power: Off, Mode: 0 (AUTO), Temp: 16C, Fan: 0 (Auto), Sleep: Off, "
+ "Swing: Off",
+ ac.toString());
+}
+
+// Decode a real message from Raw Data.
+TEST(TestDecodeTeco, RealNormalExample) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ IRTecoAc ac(0);
+ irsend.begin();
+
+ uint16_t rawData1[73] = {
+ 9076, 4442, 670, 1620, 670, 516, 670, 516, 666, 1626, 670, 516,
+ 664, 520, 666, 1626, 666, 1626, 664, 1626, 666, 1626, 666, 520,
+ 666, 1626, 666, 520, 666, 1626, 666, 520, 666, 516, 670, 514,
+ 670, 516, 666, 520, 670, 516, 666, 520, 666, 516, 672, 514, 670,
+ 516, 666, 520, 666, 516, 672, 514, 670, 516, 666, 1624, 666, 520,
+ 666, 1626, 666, 520, 666, 516, 672, 1620, 670, 516, 670};
+ uint64_t expected1 = 0b01001010000000000000010101111001001; // 0x250002BC9
+ irsend.reset();
+ irsend.sendRaw(rawData1, 73, 38);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(TECO, irsend.capture.decode_type);
+ EXPECT_EQ(kTecoBits, irsend.capture.bits);
+ EXPECT_FALSE(irsend.capture.repeat);
+ EXPECT_EQ(expected1, irsend.capture.value);
+ EXPECT_EQ(0, irsend.capture.address);
+ EXPECT_EQ(0, irsend.capture.command);
+ ac.begin();
+ ac.setRaw(irsend.capture.value);
+ EXPECT_EQ(
+ "Power: On, Mode: 1 (COOL), Temp: 27C, Fan: 0 (Auto), Sleep: On, "
+ "Swing: On",
+ ac.toString());
+
+ uint16_t rawData2[73] = {
+ 9048, 4472, 636, 548, 636, 1654, 638, 546, 642, 1650, 642, 546, 638,
+ 1654, 638, 1654, 638, 546, 638, 1654, 636, 546, 642, 1650, 640, 548,
+ 636, 548, 638, 546, 636, 546, 642, 542, 642, 546, 638, 546, 638, 546,
+ 636, 548, 642, 542, 642, 546, 636, 548, 636, 546, 642, 542, 642, 546,
+ 638, 546, 638, 546, 636, 1654, 642, 542, 642, 1650, 642, 546, 638, 546,
+ 638, 1654, 638, 546, 642}; // TECO 25000056A
+ uint64_t expected2 = 0b01001010000000000000000010101101010; // 0x25000056A
+ irsend.reset();
+ irsend.sendRaw(rawData2, 73, 38);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(TECO, irsend.capture.decode_type);
+ EXPECT_EQ(kTecoBits, irsend.capture.bits);
+ EXPECT_FALSE(irsend.capture.repeat);
+ EXPECT_EQ(expected2, irsend.capture.value);
+ EXPECT_EQ(0, irsend.capture.address);
+ EXPECT_EQ(0, irsend.capture.command);
+ ac.begin();
+ ac.setRaw(irsend.capture.value);
+ EXPECT_EQ(
+ "Power: On, Mode: 2 (DRY), Temp: 21C, Fan: 2 (Med), Sleep: Off, "
+ "Swing: On",
+ ac.toString());
+}
diff --git a/lib/IRremoteESP8266/test/ir_Vestel_test.cpp b/lib/IRremoteESP8266/test/ir_Vestel_test.cpp
index b921bf8..823b92f 100644
--- a/lib/IRremoteESP8266/test/ir_Vestel_test.cpp
+++ b/lib/IRremoteESP8266/test/ir_Vestel_test.cpp
@@ -7,15 +7,15 @@
#include "IRsend_test.h"
#include "gtest/gtest.h"
-// Tests for sendVestelAC()
+// Tests for sendVestelAc()
// Test sending typical data only.
-TEST(TestSendVestelAC, SendDataOnly) {
+TEST(TestSendVestelAc, SendDataOnly) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
- irsend.sendVestelAC(0x0F00D9001FEF201ULL);
+ irsend.sendVestelAc(0x0F00D9001FEF201ULL);
EXPECT_EQ(
"m3110s9066"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
@@ -30,12 +30,12 @@ TEST(TestSendVestelAC, SendDataOnly) {
}
// Test sending typical data with repeats.
-TEST(TestSendVestelAC, SendWithRepeats) {
+TEST(TestSendVestelAc, SendWithRepeats) {
IRsendTest irsend(0);
irsend.begin();
irsend.reset();
- irsend.sendVestelAC(0x0F00D9001FEF201ULL, kVestelACBits, 2); // two repeats.
+ irsend.sendVestelAc(0x0F00D9001FEF201ULL, kVestelAcBits, 2); // two repeats.
EXPECT_EQ(
"m3110s9066"
"m520s1535m520s480m520s480m520s480m520s480m520s480m520s480m520s480"
@@ -67,10 +67,10 @@ TEST(TestSendVestelAC, SendWithRepeats) {
irsend.outputStr());
}
-// Tests for IRVestelAC class.
+// Tests for IRVestelAc class.
-TEST(TestVestelACClass, Power) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, Power) {
+ IRVestelAc ac(0);
ac.begin();
ac.setPower(true);
@@ -90,91 +90,91 @@ TEST(TestVestelACClass, Power) {
EXPECT_FALSE(ac.isTimeCommand());
}
-TEST(TestVestelACClass, OperatingMode) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, OperatingMode) {
+ IRVestelAc ac(0);
ac.begin();
- ac.setMode(kVestelACAuto);
- EXPECT_EQ(kVestelACAuto, ac.getMode());
+ ac.setMode(kVestelAcAuto);
+ EXPECT_EQ(kVestelAcAuto, ac.getMode());
- ac.setMode(kVestelACCool);
- EXPECT_EQ(kVestelACCool, ac.getMode());
+ ac.setMode(kVestelAcCool);
+ EXPECT_EQ(kVestelAcCool, ac.getMode());
- ac.setMode(kVestelACHeat);
- EXPECT_EQ(kVestelACHeat, ac.getMode());
+ ac.setMode(kVestelAcHeat);
+ EXPECT_EQ(kVestelAcHeat, ac.getMode());
- ac.setMode(kVestelACFan);
- EXPECT_EQ(kVestelACFan, ac.getMode());
+ ac.setMode(kVestelAcFan);
+ EXPECT_EQ(kVestelAcFan, ac.getMode());
- ac.setMode(kVestelACDry);
- EXPECT_EQ(kVestelACDry, ac.getMode());
+ ac.setMode(kVestelAcDry);
+ EXPECT_EQ(kVestelAcDry, ac.getMode());
- ac.setMode(kVestelACAuto - 1);
- EXPECT_EQ(kVestelACAuto, ac.getMode());
+ ac.setMode(kVestelAcAuto - 1);
+ EXPECT_EQ(kVestelAcAuto, ac.getMode());
- ac.setMode(kVestelACCool);
- EXPECT_EQ(kVestelACCool, ac.getMode());
+ ac.setMode(kVestelAcCool);
+ EXPECT_EQ(kVestelAcCool, ac.getMode());
- ac.setMode(kVestelACHeat + 1);
- EXPECT_EQ(kVestelACAuto, ac.getMode());
+ ac.setMode(kVestelAcHeat + 1);
+ EXPECT_EQ(kVestelAcAuto, ac.getMode());
ac.setMode(255);
- EXPECT_EQ(kVestelACAuto, ac.getMode());
+ EXPECT_EQ(kVestelAcAuto, ac.getMode());
EXPECT_FALSE(ac.isTimeCommand());
}
-TEST(TestVestelACClass, Temperature) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, Temperature) {
+ IRVestelAc ac(0);
ac.begin();
- ac.setTemp(kVestelACMinTempC);
- EXPECT_EQ(kVestelACMinTempC, ac.getTemp());
+ ac.setTemp(kVestelAcMinTempC);
+ EXPECT_EQ(kVestelAcMinTempC, ac.getTemp());
- ac.setTemp(kVestelACMinTempC + 1);
- EXPECT_EQ(kVestelACMinTempC + 1, ac.getTemp());
+ ac.setTemp(kVestelAcMinTempC + 1);
+ EXPECT_EQ(kVestelAcMinTempC + 1, ac.getTemp());
- ac.setTemp(kVestelACMaxTemp);
- EXPECT_EQ(kVestelACMaxTemp, ac.getTemp());
+ ac.setTemp(kVestelAcMaxTemp);
+ EXPECT_EQ(kVestelAcMaxTemp, ac.getTemp());
- ac.setTemp(kVestelACMinTempC - 1);
- EXPECT_EQ(kVestelACMinTempC, ac.getTemp());
+ ac.setTemp(kVestelAcMinTempC - 1);
+ EXPECT_EQ(kVestelAcMinTempC, ac.getTemp());
- ac.setTemp(kVestelACMaxTemp + 1);
- EXPECT_EQ(kVestelACMaxTemp, ac.getTemp());
+ ac.setTemp(kVestelAcMaxTemp + 1);
+ EXPECT_EQ(kVestelAcMaxTemp, ac.getTemp());
ac.setTemp(23);
EXPECT_EQ(23, ac.getTemp());
ac.setTemp(0);
- EXPECT_EQ(kVestelACMinTempC, ac.getTemp());
+ EXPECT_EQ(kVestelAcMinTempC, ac.getTemp());
ac.setTemp(255);
- EXPECT_EQ(kVestelACMaxTemp, ac.getTemp());
+ EXPECT_EQ(kVestelAcMaxTemp, ac.getTemp());
EXPECT_FALSE(ac.isTimeCommand());
}
-TEST(TestVestelACClass, FanSpeed) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, FanSpeed) {
+ IRVestelAc ac(0);
ac.begin();
- ac.setFan(kVestelACFanLow);
+ ac.setFan(kVestelAcFanLow);
- ac.setFan(kVestelACFanAuto);
- EXPECT_EQ(kVestelACFanAuto, ac.getFan());
+ ac.setFan(kVestelAcFanAuto);
+ EXPECT_EQ(kVestelAcFanAuto, ac.getFan());
- ac.setFan(kVestelACFanLow);
- EXPECT_EQ(kVestelACFanLow, ac.getFan());
- ac.setFan(kVestelACFanMed);
- EXPECT_EQ(kVestelACFanMed, ac.getFan());
- ac.setFan(kVestelACFanHigh);
- EXPECT_EQ(kVestelACFanHigh, ac.getFan());
+ ac.setFan(kVestelAcFanLow);
+ EXPECT_EQ(kVestelAcFanLow, ac.getFan());
+ ac.setFan(kVestelAcFanMed);
+ EXPECT_EQ(kVestelAcFanMed, ac.getFan());
+ ac.setFan(kVestelAcFanHigh);
+ EXPECT_EQ(kVestelAcFanHigh, ac.getFan());
- ac.setFan(kVestelACFanHigh);
- EXPECT_EQ(kVestelACFanHigh, ac.getFan());
+ ac.setFan(kVestelAcFanHigh);
+ EXPECT_EQ(kVestelAcFanHigh, ac.getFan());
EXPECT_FALSE(ac.isTimeCommand());
}
-TEST(TestVestelACClass, Swing) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, Swing) {
+ IRVestelAc ac(0);
ac.begin();
ac.setSwing(true);
@@ -188,8 +188,8 @@ TEST(TestVestelACClass, Swing) {
EXPECT_FALSE(ac.isTimeCommand());
}
-TEST(TestVestelACClass, Ion) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, Ion) {
+ IRVestelAc ac(0);
ac.begin();
ac.setIon(true);
@@ -203,8 +203,8 @@ TEST(TestVestelACClass, Ion) {
EXPECT_FALSE(ac.isTimeCommand());
}
-TEST(TestVestelACClass, Turbo) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, Turbo) {
+ IRVestelAc ac(0);
ac.begin();
ac.setTurbo(true);
@@ -218,8 +218,8 @@ TEST(TestVestelACClass, Turbo) {
EXPECT_FALSE(ac.isTimeCommand());
}
-TEST(TestVestelACClass, Sleep) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, Sleep) {
+ IRVestelAc ac(0);
ac.begin();
ac.setSleep(true);
@@ -233,8 +233,8 @@ TEST(TestVestelACClass, Sleep) {
EXPECT_FALSE(ac.isTimeCommand());
}
-TEST(TestVestelACClass, Time) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, Time) {
+ IRVestelAc ac(0);
ac.begin();
ac.setTime(0);
@@ -251,8 +251,8 @@ TEST(TestVestelACClass, Time) {
EXPECT_EQ(23 * 60 + 59, ac.getTime());
}
-TEST(TestVestelACClass, OnTimer) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, OnTimer) {
+ IRVestelAc ac(0);
ac.begin();
ac.setOnTimer(0);
@@ -272,8 +272,8 @@ TEST(TestVestelACClass, OnTimer) {
EXPECT_EQ(23 * 60 + 50, ac.getOnTimer());
}
-TEST(TestVestelACClass, OffTimer) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, OffTimer) {
+ IRVestelAc ac(0);
ac.begin();
ac.setOffTimer(0);
@@ -293,8 +293,8 @@ TEST(TestVestelACClass, OffTimer) {
EXPECT_EQ(23 * 60 + 50, ac.getOffTimer());
}
-TEST(TestVestelACClass, Timer) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, Timer) {
+ IRVestelAc ac(0);
ac.begin();
ac.setTimer(0);
@@ -315,16 +315,16 @@ TEST(TestVestelACClass, Timer) {
EXPECT_EQ(0, ac.getOnTimer());
}
-TEST(TestVestelACClass, MessageConstuction) {
- IRVestelAC ac(0);
+TEST(TestVestelAcClass, MessageConstuction) {
+ IRVestelAc ac(0);
EXPECT_EQ(
"Power: On, Mode: 0 (AUTO), Temp: 25C, Fan: 13 (AUTO HOT), Sleep: Off, "
"Turbo: Off, Ion: Off, Swing: Off",
ac.toString());
- ac.setMode(kVestelACCool);
+ ac.setMode(kVestelAcCool);
ac.setTemp(21);
- ac.setFan(kVestelACFanHigh);
+ ac.setFan(kVestelAcFanHigh);
EXPECT_FALSE(ac.isTimeCommand());
EXPECT_EQ(
"Power: On, Mode: 1 (COOL), Temp: 21C, Fan: 11 (HIGH), Sleep: Off, "
@@ -341,7 +341,7 @@ TEST(TestVestelACClass, MessageConstuction) {
// Now change a few already set things.
ac.setSleep(true);
- ac.setMode(kVestelACHeat);
+ ac.setMode(kVestelAcHeat);
EXPECT_EQ(
"Power: On, Mode: 4 (HEAT), Temp: 21C, Fan: 11 (HIGH), Sleep: On, "
"Turbo: Off, Ion: On, Swing: On",
@@ -357,7 +357,7 @@ TEST(TestVestelACClass, MessageConstuction) {
EXPECT_FALSE(ac.isTimeCommand());
// Check that the checksum is valid.
- EXPECT_TRUE(IRVestelAC::validChecksum(ac.getRaw()));
+ EXPECT_TRUE(IRVestelAc::validChecksum(ac.getRaw()));
ac.setTime(23 * 60 + 59);
EXPECT_TRUE(ac.isTimeCommand());
EXPECT_EQ(
@@ -392,10 +392,10 @@ TEST(TestVestelACClass, MessageConstuction) {
ac.toString());
}
-// Tests for decodeVestelAC().
+// Tests for decodeVestelAc().
// Decode normal "synthetic" messages.
-TEST(TestDecodeVestelAC, NormalDecodeWithStrict) {
+TEST(TestDecodeVestelAc, NormalDecodeWithStrict) {
IRsendTest irsend(0);
IRrecv irrecv(0);
irsend.begin();
@@ -403,11 +403,11 @@ TEST(TestDecodeVestelAC, NormalDecodeWithStrict) {
// With the specific decoder.
uint64_t expectedState = 0x0F00D9001FEF201ULL;
irsend.reset();
- irsend.sendVestelAC(expectedState);
+ irsend.sendVestelAc(expectedState);
irsend.makeDecodeResult();
- ASSERT_TRUE(irrecv.decodeVestelAC(&irsend.capture, kVestelACBits, true));
+ ASSERT_TRUE(irrecv.decodeVestelAc(&irsend.capture, kVestelAcBits, true));
EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
- EXPECT_EQ(kVestelACBits, irsend.capture.bits);
+ EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(expectedState, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
@@ -415,17 +415,17 @@ TEST(TestDecodeVestelAC, NormalDecodeWithStrict) {
// With the all the decoders.
irsend.reset();
- irsend.sendVestelAC(expectedState);
+ irsend.sendVestelAc(expectedState);
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
- EXPECT_EQ(kVestelACBits, irsend.capture.bits);
+ EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(expectedState, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
EXPECT_EQ(0, irsend.capture.command);
- IRVestelAC ac(0);
+ IRVestelAc ac(0);
ac.begin();
ac.setRaw(irsend.capture.value);
EXPECT_EQ(
@@ -435,10 +435,10 @@ TEST(TestDecodeVestelAC, NormalDecodeWithStrict) {
}
// Decode a real message from Raw Data.
-TEST(TestDecodeVestelAC, RealNormalExample) {
+TEST(TestDecodeVestelAc, RealNormalExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
- IRVestelAC ac(0);
+ IRVestelAc ac(0);
irsend.begin();
uint16_t rawData[115] = {
@@ -457,7 +457,7 @@ TEST(TestDecodeVestelAC, RealNormalExample) {
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
- EXPECT_EQ(kVestelACBits, irsend.capture.bits);
+ EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(0xF4410001FF1201ULL, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
@@ -470,10 +470,10 @@ TEST(TestDecodeVestelAC, RealNormalExample) {
ac.toString());
}
-TEST(TestDecodeVestelAC, RealTimerExample) {
+TEST(TestDecodeVestelAc, RealTimerExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
- IRVestelAC ac(0);
+ IRVestelAc ac(0);
irsend.begin();
uint16_t rawData[115] = {
@@ -492,7 +492,7 @@ TEST(TestDecodeVestelAC, RealTimerExample) {
irsend.makeDecodeResult();
ASSERT_TRUE(irrecv.decode(&irsend.capture));
EXPECT_EQ(VESTEL_AC, irsend.capture.decode_type);
- EXPECT_EQ(kVestelACBits, irsend.capture.bits);
+ EXPECT_EQ(kVestelAcBits, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_EQ(0x2D6570B8EE201ULL, irsend.capture.value);
EXPECT_EQ(0, irsend.capture.address);
@@ -505,7 +505,7 @@ TEST(TestDecodeVestelAC, RealTimerExample) {
}
// General housekeeping
-TEST(TestDecodeVestelAC, Housekeeping) {
+TEST(TestDecodeVestelAc, Housekeeping) {
ASSERT_EQ("VESTEL_AC", typeToString(VESTEL_AC));
ASSERT_FALSE(hasACState(VESTEL_AC)); // Uses uint64_t, not uint8_t*.
}
diff --git a/lib/IRremoteESP8266/tools/Makefile b/lib/IRremoteESP8266/tools/Makefile
index 8bf2892..4f3e33e 100644
--- a/lib/IRremoteESP8266/tools/Makefile
+++ b/lib/IRremoteESP8266/tools/Makefile
@@ -48,7 +48,7 @@ PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.o \
ir_Pronto.o ir_GlobalCache.o ir_Nikai.o ir_Toshiba.o ir_Midea.o \
ir_Magiquest.o ir_Lasertag.o ir_Carrier.o ir_Haier.o ir_Hitachi.o \
ir_GICable.o ir_Whirlpool.o ir_Lutron.o ir_Electra.o ir_Pioneer.o \
- ir_MWM.o ir_Vestel.o
+ ir_MWM.o ir_Vestel.o ir_Teco.o ir_Tcl.o
# Common object files
COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o $(PROTOCOLS)
@@ -197,3 +197,9 @@ ir_MWM.o : $(USER_DIR)/ir_MWM.cpp $(USER_DIR)/ir_RC5_RC6.cpp $(COMMON_DEPS)
ir_Vestel.o : $(USER_DIR)/ir_Vestel.cpp $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Vestel.cpp
+
+ir_Teco.o : $(USER_DIR)/ir_Teco.cpp $(GTEST_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Teco.cpp
+
+ir_Tcl.o : $(USER_DIR)/ir_Tcl.cpp $(USER_DIR)/ir_Tcl.h $(GTEST_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/ir_Tcl.cpp