-#endif
-#include "IRremoteESP8266.h"
-#include "IRsend.h"
-#ifdef UNIT_TEST
-#include "IRsend_test.h"
-#endif
-
-// Constants
-const uint16_t kHitachiAcFreq = 38000; // Hz.
-const uint8_t kHitachiAcAuto = 2;
-const uint8_t kHitachiAcHeat = 3;
-const uint8_t kHitachiAcCool = 4;
-const uint8_t kHitachiAcDry = 5;
-const uint8_t kHitachiAcFan = 0xC;
-const uint8_t kHitachiAcFanAuto = 1;
-const uint8_t kHitachiAcFanLow = 2;
-const uint8_t kHitachiAcFanMed = 3;
-const uint8_t kHitachiAcFanHigh = 5;
-const uint8_t kHitachiAcMinTemp = 16; // 16C
-const uint8_t kHitachiAcMaxTemp = 32; // 32C
-const uint8_t kHitachiAcAutoTemp = 23; // 23C
-const uint8_t kHitachiAcPowerOffset = 0;
-const uint8_t kHitachiAcSwingOffset = 7;
-
-// HitachiAc424
-// Byte[11]
-const uint8_t kHitachiAc424ButtonByte = 11;
-const uint8_t kHitachiAc424ButtonPowerMode = 0x13;
-const uint8_t kHitachiAc424ButtonFan = 0x42;
-const uint8_t kHitachiAc424ButtonTempDown = 0x43;
-const uint8_t kHitachiAc424ButtonTempUp = 0x44;
-const uint8_t kHitachiAc424ButtonSwingV = 0x81;
-
-// Byte[13]
-const uint8_t kHitachiAc424TempByte = 13;
-const uint8_t kHitachiAc424TempOffset = 2;
-const uint8_t kHitachiAc424TempSize = 6;
-const uint8_t kHitachiAc424MinTemp = 16; // 16C
-const uint8_t kHitachiAc424MaxTemp = 32; // 32C
-const uint8_t kHitachiAc424FanTemp = 27; // 27C
-
-// Byte[25]
-const uint8_t kHitachiAc424ModeByte = 25;
-const uint8_t kHitachiAc424Fan = 1;
-const uint8_t kHitachiAc424Cool = 3;
-const uint8_t kHitachiAc424Dry = 5;
-const uint8_t kHitachiAc424Heat = 6;
-const uint8_t kHitachiAc424FanByte = kHitachiAc424ModeByte;
-const uint8_t kHitachiAc424FanMin = 1;
-const uint8_t kHitachiAc424FanLow = 2;
-const uint8_t kHitachiAc424FanMedium = 3;
-const uint8_t kHitachiAc424FanHigh = 4;
-const uint8_t kHitachiAc424FanAuto = 5;
-const uint8_t kHitachiAc424FanMax = 6;
-const uint8_t kHitachiAc424FanMaxDry = 2;
-// Byte[27]
-const uint8_t kHitachiAc424PowerByte = 27;
-const uint8_t kHitachiAc424PowerOn = 0xF1;
-const uint8_t kHitachiAc424PowerOff = 0xE1;
-
-// Classes
-class IRHitachiAc {
- public:
- explicit IRHitachiAc(const uint16_t pin, const bool inverted = false,
- const bool use_modulation = true);
-
- void stateReset(void);
-#if SEND_HITACHI_AC
- void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
- uint8_t calibrate(void) { return _irsend.calibrate(); }
-#endif // SEND_HITACHI_AC
- 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 speed);
- uint8_t getFan(void);
- void setMode(const uint8_t mode);
- uint8_t getMode(void);
- void setSwingVertical(const bool on);
- bool getSwingVertical(void);
- void setSwingHorizontal(const bool on);
- bool getSwingHorizontal(void);
- uint8_t* getRaw(void);
- void setRaw(const uint8_t new_code[],
- const uint16_t length = kHitachiAcStateLength);
- static bool validChecksum(const uint8_t state[],
- const uint16_t length = kHitachiAcStateLength);
- static uint8_t calcChecksum(const uint8_t state[],
- const uint16_t length = kHitachiAcStateLength);
- uint8_t convertMode(const stdAc::opmode_t mode);
- uint8_t convertFan(const stdAc::fanspeed_t speed);
- static stdAc::opmode_t toCommonMode(const uint8_t mode);
- static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
- stdAc::state_t toCommon(void);
- String toString(void);
-#ifndef UNIT_TEST
-
- private:
- IRsend _irsend;
-#else
- IRsendTest _irsend;
-#endif
- // The state of the IR remote in IR code form.
- uint8_t remote_state[kHitachiAcStateLength];
- void checksum(const uint16_t length = kHitachiAcStateLength);
- uint8_t _previoustemp;
-};
-
-class IRHitachiAc424 {
- public:
- explicit IRHitachiAc424(const uint16_t pin, const bool inverted = false,
- const bool use_modulation = true);
-
- void stateReset(void);
-#if SEND_HITACHI_AC424
- void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
- uint8_t calibrate(void) { return _irsend.calibrate(); }
-#endif // SEND_HITACHI_AC424
- void begin(void);
- void on(void);
- void off(void);
- void setPower(const bool on);
- bool getPower(void);
- void setTemp(const uint8_t temp, bool setPrevious = true);
- uint8_t getTemp(void);
- void setFan(const uint8_t speed);
- uint8_t getFan(void);
- uint8_t getButton(void);
- void setButton(const uint8_t button);
- void setSwingVToggle(const bool on);
- bool getSwingVToggle(void);
- void setMode(const uint8_t mode);
- uint8_t getMode(void);
- uint8_t* getRaw(void);
- void setRaw(const uint8_t new_code[],
- const uint16_t length = kHitachiAc424StateLength);
- uint8_t convertMode(const stdAc::opmode_t mode);
- uint8_t convertFan(const stdAc::fanspeed_t speed);
- static stdAc::opmode_t toCommonMode(const uint8_t mode);
- static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
- stdAc::state_t toCommon(void);
- String toString(void);
-#ifndef UNIT_TEST
-
- private:
- IRsend _irsend;
-#else
- IRsendTest _irsend;
-#endif
- // The state of the IR remote in IR code form.
- uint8_t remote_state[kHitachiAc424StateLength];
- void setInvertedStates(void);
- uint8_t _previoustemp;
-};
-
-#endif // IR_HITACHI_H_
diff --git a/lib/IRremoteESP8266-2.7.4/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.5/CPPLINT.cfg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/CPPLINT.cfg
rename to lib/IRremoteESP8266-2.7.5/CPPLINT.cfg
diff --git a/lib/IRremoteESP8266-2.7.4/LICENSE.txt b/lib/IRremoteESP8266-2.7.5/LICENSE.txt
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/LICENSE.txt
rename to lib/IRremoteESP8266-2.7.5/LICENSE.txt
diff --git a/lib/IRremoteESP8266-2.7.4/README.md b/lib/IRremoteESP8266-2.7.5/README.md
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/README.md
rename to lib/IRremoteESP8266-2.7.5/README.md
index 093b15cc1..9ce40166f 100644
--- a/lib/IRremoteESP8266-2.7.4/README.md
+++ b/lib/IRremoteESP8266-2.7.5/README.md
@@ -9,8 +9,8 @@
This library enables you to **send _and_ receive** infra-red signals on an [ESP8266](https://github.com/esp8266/Arduino) or an
[ESP32](https://github.com/espressif/arduino-esp32) using the [Arduino framework](https://www.arduino.cc/) using common 940nm IR LEDs and common IR receiver modules. e.g. TSOP{17,22,24,36,38,44,48}* demodulators etc.
-## v2.7.4 Now Available
-Version 2.7.4 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes.
+## v2.7.5 Now Available
+Version 2.7.5 of the library is now [available](https://github.com/crankyoldgit/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/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.
diff --git a/lib/IRremoteESP8266-2.7.4/README_fr.md b/lib/IRremoteESP8266-2.7.5/README_fr.md
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/README_fr.md
rename to lib/IRremoteESP8266-2.7.5/README_fr.md
index f95bcc945..49fc3188c 100644
--- a/lib/IRremoteESP8266-2.7.4/README_fr.md
+++ b/lib/IRremoteESP8266-2.7.5/README_fr.md
@@ -9,8 +9,8 @@
Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole
[ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc.
-## v2.7.4 disponible
-Version 2.7.4 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants.
+## v2.7.5 disponible
+Version 2.7.5 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants.
#### mise à jour depuis pre-v2.0
L'utilisation de la librairie à un peu changer depuis la version in v2.0. Si vous voulez l'utiliser vous devrez changer votre utilisation aussi. Vous pouvez vous renseigner sur les précondition d'utilisation ici : [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.
diff --git a/lib/IRremoteESP8266-2.7.4/ReleaseNotes.md b/lib/IRremoteESP8266-2.7.5/ReleaseNotes.md
similarity index 97%
rename from lib/IRremoteESP8266-2.7.4/ReleaseNotes.md
rename to lib/IRremoteESP8266-2.7.5/ReleaseNotes.md
index 4c6b1a967..51df6df27 100644
--- a/lib/IRremoteESP8266-2.7.4/ReleaseNotes.md
+++ b/lib/IRremoteESP8266-2.7.5/ReleaseNotes.md
@@ -1,5 +1,23 @@
# Release Notes
+## _v2.7.5 (20200409)_
+
+**[Features]**
+- Detailed support for `HITACHI_AC1` protocol. (#1056, #1061, #1072)
+- update sharp to match Sharp AH-A5SAY (#1074)
+- Experimental support for AIRWELL protocol. (#1069, #1070)
+- SamsungAC: Add Breeze (Aka WindFree) control (#1062, #1071)
+- Support for Daikin FFN-C A/C (#1064, #1065)
+- Add basic support for HITACHI_AC3 protocol. (#1060, #1063)
+- Add support for `SYMPHONY` 11 bit protocol. (#1057, #1058)
+- IRMQTTServer: Improve Home-Assistant discovery by sending a 'device' with the discovery packet (#1055)
+
+**[Misc]**
+- Clean up support status of various protocols.
+- Add `decodeToState()` unit tests to all supported protocols (#1067, #1068)
+- Add Gree AC example code. (#1066)
+
+
## _v2.7.4 (20200226)_
**[Bug Fixes]**
diff --git a/lib/IRremoteESP8266-2.7.4/SupportedProtocols.md b/lib/IRremoteESP8266-2.7.5/SupportedProtocols.md
similarity index 92%
rename from lib/IRremoteESP8266-2.7.4/SupportedProtocols.md
rename to lib/IRremoteESP8266-2.7.5/SupportedProtocols.md
index 04661c3bb..ed4699de2 100644
--- a/lib/IRremoteESP8266-2.7.4/SupportedProtocols.md
+++ b/lib/IRremoteESP8266-2.7.5/SupportedProtocols.md
@@ -1,18 +1,20 @@
+ Last generated: Thu Apr 9 15:49:53 2020 --->
# IR Protocols supported by this library
| Protocol | Brand | Model | A/C Model | Detailed A/C Support |
| --- | --- | --- | --- | --- |
+| [Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Airwell.cpp) | **Airwell** | RC08W remote | | - |
| [Aiwa](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Aiwa.cpp) | **Aiwa** | RC-T501 RCU | | - |
| [Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.cpp) | **[Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.h)** | ADR-853H A/C
ADR-853H A/C
TAC-444 remote
TAC-444 remote
TAC-495 remote
TAC-495 remote | | Yes |
| [Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.cpp) | **[Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.h)** | Ulisse 13 DCI Mobile Split A/C | | Yes |
| [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **Carrier/Surrey** | 42QG5A55970 remote
53NGK009/012 Inverter
619EGX0090E0 A/C
619EGX0120E0 A/C
619EGX0180E0 A/C
619EGX0220E0 A/C | | - |
+| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | RC08B remote | | Yes |
| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Beko](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | BINR 070/071 split-type A/C
BINR 070/071 split-type A/C
RG57K7(B)/BGEF Remote
RG57K7(B)/BGEF Remote | | Yes |
| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | MS12FU-10HRDN1-QRD0GW(B) A/C
MS12FU-10HRDN1-QRD0GW(B) A/C
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
RG52D/BGE Remote
RG52D/BGE Remote | | Yes |
| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Tokio](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote
AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote | | Yes |
-| [Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.cpp) | **[Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.h)** | 17 Series A/C (DAIKIN128)
ARC423A5 remote
ARC433** remote
ARC433B69 remote
ARC477A1 remote
ARC480A5 remote (DAIKIN152)
BRC4C153 remote
BRC52B63 remote (DAIKIN128)
FTE12HV2S A/C
FTXB09AXVJU A/C (DAIKIN128)
FTXB12AXVJU A/C (DAIKIN128)
FTXZ25NV1B A/C
FTXZ35NV1B A/C
FTXZ50NV1B A/C | | Yes |
+| [Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.cpp) | **[Daikin](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Daikin.h)** | 17 Series A/C (DAIKIN128)
ARC423A5 remote
ARC433** remote
ARC433B69 remote
ARC477A1 remote
ARC480A5 remote (DAIKIN152)
BRC4C153 remote
BRC52B63 remote (DAIKIN128)
DGS01 remote (DAIKIN64)
FFN-C/FCN-F Series A/C (DAIKIN64)
FTE12HV2S A/C
FTXB09AXVJU A/C (DAIKIN128)
FTXB12AXVJU A/C (DAIKIN128)
FTXZ25NV1B A/C
FTXZ35NV1B A/C
FTXZ50NV1B A/C | | Yes |
| [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Unknown** | | | - |
| [Dish](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Dish.cpp) | **DISH NETWORK** | echostar 301 | | - |
| [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[AUX](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | KFR-35GW/BpNFW=3 A/C
YKR-T/011 remote | | Yes |
@@ -28,7 +30,7 @@
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[RusClimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | EACS/I-09HAR_X/N3 A/C
YAW1F remote | YAW1F
YBOFB | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Ultimate](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | Heat Pump | YAW1F
YBOFB | Yes |
| [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | HSU-09HMC203 A/C
HSU07-HEA03 remote
YR-W02 remote | | Yes |
-| [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | LT0541-HTA remote
RAR-8P2 remote
RAS-35THA6 remote
RAS-AJ25H A/C
Series VI A/C (Circa 2007) | | Yes |
+| [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | KAZE-312KSDP A/C (HITACHI_AC1)
LT0541-HTA remote
PC-LH3B (HITACHI_AC3)
R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
RAR-8P2 remote
RAS-35THA6 remote
RAS-AJ25H A/C
Series VI A/C (Circa 2007) | | Yes |
| [Inax](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Inax.cpp) | **Lixil** | Inax DT-BA283 Toilet | | - |
| [JVC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_JVC.cpp) | **Unknown** | | | - |
| [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | YAPOF3 remote | | Yes |
@@ -56,11 +58,12 @@
| [Pronto](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Pronto.cpp) | **Unknown** | | | - |
| [RC5_RC6](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RC5_RC6.cpp) | **Unknown** | | | - |
| [RCMM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_RCMM.cpp) | **Microsoft** | XBOX 360 | | - |
-| [Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.cpp) | **[Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.h)** | AR09FSSDAWKNFA A/C
AR12HSSDBWKNEU A/C
AR12KSFPEWQNET A/C
DB63-03556X003 remote
IEC-R03 remote
UA55H6300 TV | | Yes |
+| [Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.cpp) | **[Samsung](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Samsung.h)** | AR09FSSDAWKNFA A/C
AR12HSSDBWKNEU A/C
AR12KSFPEWQNET A/C
AR12NXCXAWKXEU A/C
DB63-03556X003 remote
DB93-16761C remote
IEC-R03 remote
UA55H6300 TV | | Yes |
| [Sanyo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sanyo.cpp) | **Unknown** | | | - |
-| [Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.h)** | AY-ZP40KR A/C
LC-52D62U TV | | Yes |
+| [Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sharp.h)** | AH-AxSAY A/C
AY-ZP40KR A/C
LC-52D62U TV | | Yes |
| [Sherwood](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sherwood.cpp) | **Sherwood** | RC-138 remote
RD6505(B) Receiver | | - |
| [Sony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Sony.cpp) | **Sony** | HT-CT380 Soundbar (Uses 38kHz & 3 repeats) | | - |
+| [Symphony](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Symphony.cpp) | **Symphony** | Air Cooler 3Di | | - |
| [Tcl](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.cpp) | **[Leberg](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.h)** | LBS-TOR07 A/C | | Yes |
| [Teco](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.cpp) | **[Alaska](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.h)** | SAC9010QC A/C
SAC9010QC remote | | Yes |
| [Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.h)** | Akita EVO II
RAS 18SKP-ES
RAS-B13N3KV2
RAS-B13N3KVP-E
WC-L03SE
WH-TA04NE | | Yes |
@@ -81,6 +84,7 @@
## Send & decodable protocols:
+- AIRWELL
- AIWA_RC_T501
- AMCOR
- ARGO
@@ -93,6 +97,7 @@
- DAIKIN176
- DAIKIN2
- DAIKIN216
+- DAIKIN64
- DENON
- DISH
- ELECTRA_AC
@@ -106,6 +111,7 @@
- HITACHI_AC
- HITACHI_AC1
- HITACHI_AC2
+- HITACHI_AC3
- HITACHI_AC424
- INAX
- JVC
@@ -144,6 +150,7 @@
- SHARP
- SHARP_AC
- SONY
+- SYMPHONY
- TCL112AC
- TECO
- TOSHIBA_AC
diff --git a/lib/IRremoteESP8266-2.7.4/examples/CommonAcControl/CommonAcControl.ino b/lib/IRremoteESP8266-2.7.5/examples/CommonAcControl/CommonAcControl.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/CommonAcControl/CommonAcControl.ino
rename to lib/IRremoteESP8266-2.7.5/examples/CommonAcControl/CommonAcControl.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/CommonAcControl/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/CommonAcControl/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/CommonAcControl/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/CommonAcControl/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/ControlSamsungAC/ControlSamsungAC.ino b/lib/IRremoteESP8266-2.7.5/examples/ControlSamsungAC/ControlSamsungAC.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/ControlSamsungAC/ControlSamsungAC.ino
rename to lib/IRremoteESP8266-2.7.5/examples/ControlSamsungAC/ControlSamsungAC.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/ControlSamsungAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/ControlSamsungAC/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/ControlSamsungAC/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/ControlSamsungAC/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/DumbIRRepeater/DumbIRRepeater.ino b/lib/IRremoteESP8266-2.7.5/examples/DumbIRRepeater/DumbIRRepeater.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/DumbIRRepeater/DumbIRRepeater.ino
rename to lib/IRremoteESP8266-2.7.5/examples/DumbIRRepeater/DumbIRRepeater.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/DumbIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/DumbIRRepeater/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/DumbIRRepeater/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/DumbIRRepeater/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRGCSendDemo/IRGCSendDemo.ino b/lib/IRremoteESP8266-2.7.5/examples/IRGCSendDemo/IRGCSendDemo.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRGCSendDemo/IRGCSendDemo.ino
rename to lib/IRremoteESP8266-2.7.5/examples/IRGCSendDemo/IRGCSendDemo.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRGCSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRGCSendDemo/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRGCSendDemo/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/IRGCSendDemo/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRGCTCPServer/IRGCTCPServer.ino b/lib/IRremoteESP8266-2.7.5/examples/IRGCTCPServer/IRGCTCPServer.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRGCTCPServer/IRGCTCPServer.ino
rename to lib/IRremoteESP8266-2.7.5/examples/IRGCTCPServer/IRGCTCPServer.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRGCTCPServer/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRGCTCPServer/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRGCTCPServer/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/IRGCTCPServer/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRMQTTServer/IRMQTTServer.h b/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.h
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/examples/IRMQTTServer/IRMQTTServer.h
rename to lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.h
index b363d98b9..b6fe281da 100644
--- a/lib/IRremoteESP8266-2.7.4/examples/IRMQTTServer/IRMQTTServer.h
+++ b/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.h
@@ -239,7 +239,7 @@ const uint16_t kJsonAcStateMaxSize = 1024; // Bytes
// ----------------- End of User Configuration Section -------------------------
// Constants
-#define _MY_VERSION_ "v1.4.6"
+#define _MY_VERSION_ "v1.4.7"
const uint8_t kRebootTime = 15; // Seconds
const uint8_t kQuickDisplayTime = 2; // Seconds
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRMQTTServer/IRMQTTServer.ino b/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.ino
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/examples/IRMQTTServer/IRMQTTServer.ino
rename to lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.ino
index efcf25431..af98e3166 100644
--- a/lib/IRremoteESP8266-2.7.4/examples/IRMQTTServer/IRMQTTServer.ino
+++ b/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/IRMQTTServer.ino
@@ -449,6 +449,7 @@ String MqttClimate; // Sub-topic for the climate topics.
String MqttClimateCmnd; // Sub-topic for the climate command topics.
#if MQTT_DISCOVERY_ENABLE
String MqttDiscovery;
+String MqttUniqueId;
#endif // MQTT_DISCOVERY_ENABLE
String MqttHAName;
String MqttClientId;
@@ -1228,6 +1229,7 @@ void handleInfo(void) {
"General
"
"Hostname: " + String(Hostname) + "
"
"IP address: " + WiFi.localIP().toString() + "
"
+ "MAC address: " + WiFi.macAddress() + "
"
"Booted: " + timeSince(1) + "
" +
"Version: " _MY_VERSION_ "
"
"Built: " __DATE__
@@ -1516,6 +1518,23 @@ bool parseStringAndSendAirCon(IRsend *irsend, const decode_type_t irType,
// Lastly, it should never exceed the maximum "normal" size.
stateSize = std::min(stateSize, kFujitsuAcStateLength);
break;
+ case HITACHI_AC3:
+ // HitachiAc3 has two distinct & different size states, so make a best
+ // guess which one we are being presented with based on the number of
+ // hexadecimal digits provided. i.e. Zero-pad if you need to to get
+ // the correct length/byte size.
+ stateSize = inputLength / 2; // Every two hex chars is a byte.
+ // Use at least the minimum size.
+ stateSize = std::max(stateSize,
+ (uint16_t) (kHitachiAc3MinStateLength));
+ // If we think it isn't a "short" message.
+ if (stateSize > kHitachiAc3MinStateLength)
+ // Then it probably the "normal" size.
+ stateSize = std::max(stateSize,
+ (uint16_t) (kHitachiAc3StateLength));
+ // Lastly, it should never exceed the maximum "normal" size.
+ stateSize = std::min(stateSize, kHitachiAc3StateLength);
+ break;
case MWM:
// MWM has variable size states, so make a best guess
// which one we are being presented with based on the number of
@@ -2033,6 +2052,8 @@ void init_vars(void) {
// Sub-topic for the climate stat topics.
#if MQTT_DISCOVERY_ENABLE
MqttDiscovery = "homeassistant/climate/" + String(Hostname) + "/config";
+ MqttUniqueId = WiFi.macAddress();
+ MqttUniqueId.replace(":", "");
#endif // MQTT_DISCOVERY_ENABLE
MqttHAName = String(Hostname) + "_aircon";
// Create a unique MQTT client id.
@@ -2531,7 +2552,16 @@ void sendMQTTDiscovery(const char *topic) {
"\"swing_mode_stat_t\":\"~/" MQTT_CLIMATE_STAT "/" KEY_SWINGV "\","
"\"swing_modes\":[\"" D_STR_OFF "\",\"" D_STR_AUTO "\",\"" D_STR_HIGHEST
"\",\"" D_STR_HIGH "\",\"" D_STR_MIDDLE "\",\""
- D_STR_LOW "\",\"" D_STR_LOWEST "\"]"
+ D_STR_LOW "\",\"" D_STR_LOWEST "\"],"
+ "\"uniq_id\":\"" + MqttUniqueId + "\","
+ "\"device\":{"
+ "\"identifiers\":[\"" + MqttUniqueId + "\"],"
+ "\"connections\":[[\"mac\",\"" + WiFi.macAddress() + "\"]],"
+ "\"manufacturer\":\"IRremoteESP8266\","
+ "\"model\":\"IRMQTTServer\","
+ "\"name\":\"" + Hostname + "\","
+ "\"sw_version\":\"" _MY_VERSION_ "\""
+ "}"
"}").c_str(), true)) {
mqttLog("MQTT climate discovery successful sent.");
hasDiscoveryBeenSent = true;
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRMQTTServer/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRMQTTServer/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/IRMQTTServer/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRServer/IRServer.ino b/lib/IRremoteESP8266-2.7.5/examples/IRServer/IRServer.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRServer/IRServer.ino
rename to lib/IRremoteESP8266-2.7.5/examples/IRServer/IRServer.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRServer/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRServer/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRServer/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/IRServer/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRrecvDemo/IRrecvDemo.ino b/lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/IRrecvDemo.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRrecvDemo/IRrecvDemo.ino
rename to lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/IRrecvDemo.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRrecvDemo/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRrecvDemo/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/IRrecvDemo/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRrecvDump/IRrecvDump.ino b/lib/IRremoteESP8266-2.7.5/examples/IRrecvDump/IRrecvDump.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRrecvDump/IRrecvDump.ino
rename to lib/IRremoteESP8266-2.7.5/examples/IRrecvDump/IRrecvDump.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRrecvDump/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRrecvDump/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRrecvDump/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/IRrecvDump/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRrecvDumpV2/IRrecvDumpV2.ino b/lib/IRremoteESP8266-2.7.5/examples/IRrecvDumpV2/IRrecvDumpV2.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRrecvDumpV2/IRrecvDumpV2.ino
rename to lib/IRremoteESP8266-2.7.5/examples/IRrecvDumpV2/IRrecvDumpV2.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRrecvDumpV2/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRrecvDumpV2/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRrecvDumpV2/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/IRrecvDumpV2/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRsendDemo/IRsendDemo.ino b/lib/IRremoteESP8266-2.7.5/examples/IRsendDemo/IRsendDemo.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRsendDemo/IRsendDemo.ino
rename to lib/IRremoteESP8266-2.7.5/examples/IRsendDemo/IRsendDemo.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRsendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRsendDemo/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRsendDemo/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/IRsendDemo/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRsendProntoDemo/IRsendProntoDemo.ino b/lib/IRremoteESP8266-2.7.5/examples/IRsendProntoDemo/IRsendProntoDemo.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRsendProntoDemo/IRsendProntoDemo.ino
rename to lib/IRremoteESP8266-2.7.5/examples/IRsendProntoDemo/IRsendProntoDemo.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/IRsendProntoDemo/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/IRsendProntoDemo/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/IRsendProntoDemo/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/IRsendProntoDemo/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino b/lib/IRremoteESP8266-2.7.5/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino
rename to lib/IRremoteESP8266-2.7.5/examples/JVCPanasonicSendDemo/JVCPanasonicSendDemo.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/JVCPanasonicSendDemo/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/JVCPanasonicSendDemo/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/JVCPanasonicSendDemo/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/JVCPanasonicSendDemo/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/LGACSend/LGACSend.ino b/lib/IRremoteESP8266-2.7.5/examples/LGACSend/LGACSend.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/LGACSend/LGACSend.ino
rename to lib/IRremoteESP8266-2.7.5/examples/LGACSend/LGACSend.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/LGACSend/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/LGACSend/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/LGACSend/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/LGACSend/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/SmartIRRepeater/SmartIRRepeater.ino b/lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/SmartIRRepeater.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/SmartIRRepeater/SmartIRRepeater.ino
rename to lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/SmartIRRepeater.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/SmartIRRepeater/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/SmartIRRepeater/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/SmartIRRepeater/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnArgoAC/TurnOnArgoAC.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnArgoAC/TurnOnArgoAC.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnArgoAC/TurnOnArgoAC.ino
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnArgoAC/TurnOnArgoAC.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnArgoAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnArgoAC/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnArgoAC/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnArgoAC/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnDaikinAC/TurnOnDaikinAC.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnDaikinAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnDaikinAC/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnDaikinAC/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnDaikinAC/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnFujitsuAC/TurnOnFujitsuAC.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnFujitsuAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnFujitsuAC/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnFujitsuAC/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnFujitsuAC/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/TurnOnGreeAC.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/TurnOnGreeAC.ino
new file mode 100644
index 000000000..64c857f3d
--- /dev/null
+++ b/lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/TurnOnGreeAC.ino
@@ -0,0 +1,77 @@
+/* Copyright 2016, 2018 David Conran
+* Copyright 2020 Sadid Rafsun Tulon
+*
+* An IR LED circuit *MUST* be connected to the ESP8266 on a pin
+* as specified by kIrLed below.
+*
+* TL;DR: The IR LED needs to be driven by a transistor for a good result.
+*
+* Suggested circuit:
+* https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-sending
+*
+* Common mistakes & tips:
+* * Don't just connect the IR LED directly to the pin, it won't
+* have enough current to drive the IR LED effectively.
+* * Make sure you have the IR LED polarity correct.
+* See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity
+* * Typical digital camera/phones can be used to see if the IR LED is flashed.
+* Replace the IR LED with a normal LED if you don't have a digital camera
+* when debugging.
+* * Avoid using the following pins unless you really know what you are doing:
+* * Pin 0/D3: Can interfere with the boot/program mode & support circuits.
+* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere.
+* * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere.
+* * ESP-01 modules are tricky. We suggest you use a module with more GPIOs
+* for your first time. e.g. ESP-12 etc.
+*/
+#include
+#include
+#include
+#include
+
+const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2).
+IRGreeAC ac(kIrLed); // Set the GPIO to be used for sending messages.
+
+void printState() {
+ // Display the settings.
+ Serial.println("GREE A/C remote is in the following state:");
+ Serial.printf(" %s\n", ac.toString().c_str());
+ // Display the encoded IR sequence.
+ unsigned char* ir_code = ac.getRaw();
+ Serial.print("IR Code: 0x");
+ for (uint8_t i = 0; i < kGreeStateLength; i++)
+ Serial.printf("%02X", ir_code[i]);
+ Serial.println();
+}
+
+void setup() {
+ ac.begin();
+ Serial.begin(115200);
+ delay(200);
+
+ // Set up what we want to send. See ir_Gree.cpp for all the options.
+ // Most things default to off.
+ Serial.println("Default state of the remote.");
+ printState();
+ Serial.println("Setting desired state for A/C.");
+ ac.on();
+ ac.setFan(1);
+ // kGreeAuto, kGreeDry, kGreeCool, kGreeFan, kGreeHeat
+ ac.setMode(kGreeCool);
+ ac.setTemp(20); // 16-30C
+ ac.setSwingVertical(true, kGreeSwingAuto);
+ ac.setXFan(false);
+ ac.setLight(false);
+ ac.setSleep(false);
+ ac.setTurbo(false);
+}
+
+void loop() {
+ // Now send the IR signal.
+#if SEND_GREE
+ Serial.println("Sending IR command to A/C ...");
+ ac.send();
+#endif // SEND_GREE
+ printState();
+ delay(5000);
+}
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnKelvinatorAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnKelvinatorAC/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnGreeAC/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnMitsubishiAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnKelvinatorAC/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnMitsubishiAC/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnKelvinatorAC/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnMitsubishiHeavyAc/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiAC/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnMitsubishiHeavyAc/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiAC/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiHeavyAc/TurnOnMitsubishiHeavyAc.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnPanasonicAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiHeavyAc/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnPanasonicAC/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnMitsubishiHeavyAc/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnPanasonicAC/TurnOnPanasonicAC.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnToshibaAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnPanasonicAC/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnToshibaAC/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnPanasonicAC/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnToshibaAC/TurnOnToshibaAC.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnTrotecAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnToshibaAC/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnTrotecAC/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnToshibaAC/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino b/lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino
rename to lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino
diff --git a/lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/platformio.ini
new file mode 100644
index 000000000..e6f6320da
--- /dev/null
+++ b/lib/IRremoteESP8266-2.7.5/examples/TurnOnTrotecAC/platformio.ini
@@ -0,0 +1,17 @@
+[platformio]
+src_dir = .
+
+[env]
+lib_extra_dirs = ../../
+lib_ldf_mode = deep+
+lib_ignore = examples
+framework = arduino
+build_flags = ; -D_IR_LOCALE_=en-AU
+
+[env:nodemcuv2]
+platform = espressif8266
+board = nodemcuv2
+
+[env:esp32dev]
+platform = espressif32
+board = esp32dev
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/README.md b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/README.md
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/README.md
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/README.md
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/Web-AC-control.ino b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/Web-AC-control.ino
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/Web-AC-control.ino
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/Web-AC-control.ino
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/platformio.ini b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/platformio.ini
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/platformio.ini
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/platformio.ini
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/printscreen.png b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/printscreen.png
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/printscreen.png
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/printscreen.png
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/favicon.ico b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/favicon.ico
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/favicon.ico
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/favicon.ico
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_1_off.svg b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_1_off.svg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_1_off.svg
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_1_off.svg
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_1_on.svg b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_1_on.svg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_1_on.svg
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_1_on.svg
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_2_off.svg b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_2_off.svg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_2_off.svg
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_2_off.svg
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_2_on.svg b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_2_on.svg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_2_on.svg
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_2_on.svg
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_3_off.svg b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_3_off.svg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_3_off.svg
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_3_off.svg
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_3_on.svg b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_3_on.svg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_3_on.svg
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_3_on.svg
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_4_off.svg b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_4_off.svg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_4_off.svg
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_4_off.svg
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_4_on.svg b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_4_on.svg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/level_4_on.svg
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/level_4_on.svg
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/ui.html b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/ui.html
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/ui.html
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/ui.html
diff --git a/lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/ui.js b/lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/ui.js
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/examples/Web-AC-control/upload/ui.js
rename to lib/IRremoteESP8266-2.7.5/examples/Web-AC-control/upload/ui.js
diff --git a/lib/IRremoteESP8266-2.7.4/keywords.txt b/lib/IRremoteESP8266-2.7.5/keywords.txt
similarity index 94%
rename from lib/IRremoteESP8266-2.7.4/keywords.txt
rename to lib/IRremoteESP8266-2.7.5/keywords.txt
index 077c0bc74..2d0ea9255 100644
--- a/lib/IRremoteESP8266-2.7.4/keywords.txt
+++ b/lib/IRremoteESP8266-2.7.5/keywords.txt
@@ -29,6 +29,7 @@ IRDaikin160 KEYWORD1
IRDaikin176 KEYWORD1
IRDaikin2 KEYWORD1
IRDaikin216 KEYWORD1
+IRDaikin64 KEYWORD1
IRDaikinESP KEYWORD1
IRElectraAc KEYWORD1
IRFujitsuAC KEYWORD1
@@ -37,6 +38,8 @@ IRGreeAC KEYWORD1
IRHaierAC KEYWORD1
IRHaierACYRW02 KEYWORD1
IRHitachiAc KEYWORD1
+IRHitachiAc1 KEYWORD1
+IRHitachiAc3 KEYWORD1
IRHitachiAc424 KEYWORD1
IRKelvinatorAC KEYWORD1
IRLgAc KEYWORD1
@@ -66,6 +69,7 @@ decode_type_t KEYWORD1
fanspeed_t KEYWORD1
fujitsu_ac_remote_model_t KEYWORD1
gree_ac_remote_model_t KEYWORD1
+hitachi_ac1_remote_model_t KEYWORD1
irparams_t KEYWORD1
lg_ac_remote_model_t KEYWORD1
match_result_t KEYWORD1
@@ -141,7 +145,9 @@ daikin160 KEYWORD2
daikin176 KEYWORD2
daikin2 KEYWORD2
daikin216 KEYWORD2
+daikin64 KEYWORD2
decode KEYWORD2
+decodeAirwell KEYWORD2
decodeAiwaRCT501 KEYWORD2
decodeAmcor KEYWORD2
decodeArgo KEYWORD2
@@ -155,6 +161,7 @@ decodeDaikin160 KEYWORD2
decodeDaikin176 KEYWORD2
decodeDaikin2 KEYWORD2
decodeDaikin216 KEYWORD2
+decodeDaikin64 KEYWORD2
decodeDenon KEYWORD2
decodeElectraAC KEYWORD2
decodeEpson KEYWORD2
@@ -166,6 +173,7 @@ decodeHaierAC KEYWORD2
decodeHaierACYRW02 KEYWORD2
decodeHash KEYWORD2
decodeHitachiAC KEYWORD2
+decodeHitachiAc3 KEYWORD2
decodeHitachiAc424 KEYWORD2
decodeInax KEYWORD2
decodeJVC KEYWORD2
@@ -200,6 +208,7 @@ decodeSanyoLC7461 KEYWORD2
decodeSharp KEYWORD2
decodeSharpAc KEYWORD2
decodeSony KEYWORD2
+decodeSymphony KEYWORD2
decodeTeco KEYWORD2
decodeToState KEYWORD2
decodeToshibaAC KEYWORD2
@@ -243,6 +252,7 @@ get3D KEYWORD2
get8CHeat KEYWORD2
getBeep KEYWORD2
getBit KEYWORD2
+getBreeze KEYWORD2
getBufSize KEYWORD2
getButton KEYWORD2
getClean KEYWORD2
@@ -280,15 +290,18 @@ getMode KEYWORD2
getMold KEYWORD2
getNight KEYWORD2
getOffTime KEYWORD2
+getOffTimeEnabled KEYWORD2
getOffTimer KEYWORD2
getOffTimerEnabled KEYWORD2
getOnTime KEYWORD2
+getOnTimeEnabled KEYWORD2
getOnTimer KEYWORD2
getOnTimerEnabled KEYWORD2
getOutsideQuiet KEYWORD2
getPower KEYWORD2
getPowerToggle KEYWORD2
getPowerful KEYWORD2
+getPreviousPower KEYWORD2
getPurify KEYWORD2
getQuiet KEYWORD2
getRClevel KEYWORD2
@@ -309,6 +322,7 @@ getSuper KEYWORD2
getSwing KEYWORD2
getSwingH KEYWORD2
getSwingHorizontal KEYWORD2
+getSwingToggle KEYWORD2
getSwingV KEYWORD2
getSwingVToggle KEYWORD2
getSwingVertical KEYWORD2
@@ -336,8 +350,10 @@ haier KEYWORD2
haierYrwo2 KEYWORD2
handleSpecialState KEYWORD2
hasACState KEYWORD2
+hasInvertedStates KEYWORD2
hasStateChanged KEYWORD2
hitachi KEYWORD2
+hitachi1 KEYWORD2
hitachi424 KEYWORD2
htmlEscape KEYWORD2
initState KEYWORD2
@@ -364,6 +380,7 @@ matchAtLeast KEYWORD2
matchBytes KEYWORD2
matchData KEYWORD2
matchGeneric KEYWORD2
+matchManchester KEYWORD2
matchMark KEYWORD2
matchSpace KEYWORD2
midea KEYWORD2
@@ -394,6 +411,7 @@ reverseBits KEYWORD2
samsung KEYWORD2
send KEYWORD2
sendAc KEYWORD2
+sendAirwell KEYWORD2
sendAiwaRCT501 KEYWORD2
sendAmcor KEYWORD2
sendArgo KEYWORD2
@@ -407,6 +425,7 @@ sendDaikin160 KEYWORD2
sendDaikin176 KEYWORD2
sendDaikin2 KEYWORD2
sendDaikin216 KEYWORD2
+sendDaikin64 KEYWORD2
sendData KEYWORD2
sendDenon KEYWORD2
sendElectraAC KEYWORD2
@@ -423,6 +442,7 @@ sendHaierACYRW02 KEYWORD2
sendHitachiAC KEYWORD2
sendHitachiAC1 KEYWORD2
sendHitachiAC2 KEYWORD2
+sendHitachiAc3 KEYWORD2
sendHitachiAc424 KEYWORD2
sendInax KEYWORD2
sendJVC KEYWORD2
@@ -434,6 +454,8 @@ sendLegoPf KEYWORD2
sendLutron KEYWORD2
sendMWM KEYWORD2
sendMagiQuest KEYWORD2
+sendManchester KEYWORD2
+sendManchesterData KEYWORD2
sendMidea KEYWORD2
sendMitsubishi KEYWORD2
sendMitsubishi112 KEYWORD2
@@ -466,6 +488,7 @@ sendSharpRaw KEYWORD2
sendSherwood KEYWORD2
sendSony KEYWORD2
sendSony38 KEYWORD2
+sendSymphony KEYWORD2
sendTcl112Ac KEYWORD2
sendTeco KEYWORD2
sendToshibaAC KEYWORD2
@@ -480,6 +503,7 @@ setAuto KEYWORD2
setBeep KEYWORD2
setBit KEYWORD2
setBits KEYWORD2
+setBreeze KEYWORD2
setButton KEYWORD2
setClean KEYWORD2
setClock KEYWORD2
@@ -516,9 +540,13 @@ setMode KEYWORD2
setModel KEYWORD2
setMold KEYWORD2
setNight KEYWORD2
+setOffTime KEYWORD2
+setOffTimeEnabled KEYWORD2
setOffTimer KEYWORD2
setOffTimerActive KEYWORD2
setOffTimerEnabled KEYWORD2
+setOnTime KEYWORD2
+setOnTimeEnabled KEYWORD2
setOnTimer KEYWORD2
setOnTimerActive KEYWORD2
setOnTimerEnabled KEYWORD2
@@ -526,6 +554,7 @@ setOutsideQuiet KEYWORD2
setPower KEYWORD2
setPowerToggle KEYWORD2
setPowerful KEYWORD2
+setPreviousPower KEYWORD2
setPurify KEYWORD2
setQuiet KEYWORD2
setRaw KEYWORD2
@@ -543,6 +572,7 @@ setSuper KEYWORD2
setSwing KEYWORD2
setSwingH KEYWORD2
setSwingHorizontal KEYWORD2
+setSwingToggle KEYWORD2
setSwingV KEYWORD2
setSwingVToggle KEYWORD2
setSwingVertical KEYWORD2
@@ -600,6 +630,7 @@ xorBytes KEYWORD2
#######################################
// LITERAL1
+AIRWELL LITERAL1
AIWA_RC_T501 LITERAL1
AIWA_RC_T501_BITS LITERAL1
AKB75215403 LITERAL1
@@ -644,6 +675,7 @@ DAIKIN160 LITERAL1
DAIKIN176 LITERAL1
DAIKIN2 LITERAL1
DAIKIN216 LITERAL1
+DAIKIN64 LITERAL1
DAIKIN_AUTO LITERAL1
DAIKIN_COMMAND_LENGTH LITERAL1
DAIKIN_COOL LITERAL1
@@ -657,6 +689,7 @@ DAIKIN_HEAT LITERAL1
DAIKIN_MAX_TEMP LITERAL1
DAIKIN_MIN_TEMP LITERAL1
DECODE_AC LITERAL1
+DECODE_AIRWELL LITERAL1
DECODE_AIWA_RC_T501 LITERAL1
DECODE_AMCOR LITERAL1
DECODE_ARGO LITERAL1
@@ -669,6 +702,7 @@ DECODE_DAIKIN160 LITERAL1
DECODE_DAIKIN176 LITERAL1
DECODE_DAIKIN2 LITERAL1
DECODE_DAIKIN216 LITERAL1
+DECODE_DAIKIN64 LITERAL1
DECODE_DENON LITERAL1
DECODE_DISH LITERAL1
DECODE_ELECTRA_AC LITERAL1
@@ -684,6 +718,7 @@ DECODE_HASH LITERAL1
DECODE_HITACHI_AC LITERAL1
DECODE_HITACHI_AC1 LITERAL1
DECODE_HITACHI_AC2 LITERAL1
+DECODE_HITACHI_AC3 LITERAL1
DECODE_HITACHI_AC424 LITERAL1
DECODE_INAX LITERAL1
DECODE_JVC LITERAL1
@@ -719,6 +754,7 @@ DECODE_SHARP LITERAL1
DECODE_SHARP_AC LITERAL1
DECODE_SHERWOOD LITERAL1
DECODE_SONY LITERAL1
+DECODE_SYMPHONY LITERAL1
DECODE_TCL112AC LITERAL1
DECODE_TECO LITERAL1
DECODE_TOSHIBA_AC LITERAL1
@@ -855,6 +891,7 @@ HITACHI_AC1_STATE_LENGTH LITERAL1
HITACHI_AC2 LITERAL1
HITACHI_AC2_BITS LITERAL1
HITACHI_AC2_STATE_LENGTH LITERAL1
+HITACHI_AC3 LITERAL1
HITACHI_AC424 LITERAL1
HITACHI_AC_BITS LITERAL1
HITACHI_AC_STATE_LENGTH LITERAL1
@@ -950,6 +987,8 @@ RC6_36_BITS LITERAL1
RC6_MODE0_BITS LITERAL1
RCMM LITERAL1
RCMM_BITS LITERAL1
+R_LT0541_HTA_A LITERAL1
+R_LT0541_HTA_B LITERAL1
SAMSUNG LITERAL1
SAMSUNG36 LITERAL1
SAMSUNG_AC LITERAL1
@@ -958,6 +997,7 @@ SANYO LITERAL1
SANYO_LC7461 LITERAL1
SANYO_LC7461_BITS LITERAL1
SANYO_SA8650B_BITS LITERAL1
+SEND_AIRWELL LITERAL1
SEND_AIWA_RC_T501 LITERAL1
SEND_AMCOR LITERAL1
SEND_ARGO LITERAL1
@@ -970,6 +1010,7 @@ SEND_DAIKIN160 LITERAL1
SEND_DAIKIN176 LITERAL1
SEND_DAIKIN2 LITERAL1
SEND_DAIKIN216 LITERAL1
+SEND_DAIKIN64 LITERAL1
SEND_DENON LITERAL1
SEND_DISH LITERAL1
SEND_ELECTRA_AC LITERAL1
@@ -984,6 +1025,7 @@ SEND_HAIER_AC_YRW02 LITERAL1
SEND_HITACHI_AC LITERAL1
SEND_HITACHI_AC1 LITERAL1
SEND_HITACHI_AC2 LITERAL1
+SEND_HITACHI_AC3 LITERAL1
SEND_HITACHI_AC424 LITERAL1
SEND_INAX LITERAL1
SEND_JVC LITERAL1
@@ -1020,6 +1062,7 @@ SEND_SHARP LITERAL1
SEND_SHARP_AC LITERAL1
SEND_SHERWOOD LITERAL1
SEND_SONY LITERAL1
+SEND_SYMPHONY LITERAL1
SEND_TCL112AC LITERAL1
SEND_TECO LITERAL1
SEND_TOSHIBA_AC LITERAL1
@@ -1037,6 +1080,7 @@ SONY_12_BITS LITERAL1
SONY_15_BITS LITERAL1
SONY_20_BITS LITERAL1
SONY_38K LITERAL1
+SYMPHONY LITERAL1
TCL112AC LITERAL1
TECO LITERAL1
TIMEOUT_MS LITERAL1
@@ -1076,6 +1120,13 @@ k3DStr LITERAL1
k6thSenseStr LITERAL1
k8CHeatStr LITERAL1
kAirFlowStr LITERAL1
+kAirwellBits LITERAL1
+kAirwellFooterMark LITERAL1
+kAirwellHalfClockPeriod LITERAL1
+kAirwellHdrMark LITERAL1
+kAirwellHdrSpace LITERAL1
+kAirwellMinRepeats LITERAL1
+kAirwellOverhead LITERAL1
kAiwaRcT501Bits LITERAL1
kAiwaRcT501MinRepeats LITERAL1
kAiwaRcT501PostBits LITERAL1
@@ -1498,6 +1549,53 @@ kDaikin2SwingVLow LITERAL1
kDaikin2SwingVSwing LITERAL1
kDaikin2Tolerance LITERAL1
kDaikin2ZeroSpace LITERAL1
+kDaikin64BitMark LITERAL1
+kDaikin64Bits LITERAL1
+kDaikin64ChecksumOffset LITERAL1
+kDaikin64ChecksumSize LITERAL1
+kDaikin64ClockHoursSize LITERAL1
+kDaikin64ClockMinsSize LITERAL1
+kDaikin64ClockOffset LITERAL1
+kDaikin64ClockSize LITERAL1
+kDaikin64Cool LITERAL1
+kDaikin64DefaultRepeat LITERAL1
+kDaikin64Dry LITERAL1
+kDaikin64Fan LITERAL1
+kDaikin64FanAuto LITERAL1
+kDaikin64FanHigh LITERAL1
+kDaikin64FanLow LITERAL1
+kDaikin64FanMed LITERAL1
+kDaikin64FanOffset LITERAL1
+kDaikin64FanQuiet LITERAL1
+kDaikin64FanSize LITERAL1
+kDaikin64FanTurbo LITERAL1
+kDaikin64Freq LITERAL1
+kDaikin64Gap LITERAL1
+kDaikin64HdrMark LITERAL1
+kDaikin64HdrSpace LITERAL1
+kDaikin64KnownGoodState LITERAL1
+kDaikin64LdrMark LITERAL1
+kDaikin64LdrSpace LITERAL1
+kDaikin64MaxTemp LITERAL1
+kDaikin64MinTemp LITERAL1
+kDaikin64ModeOffset LITERAL1
+kDaikin64ModeSize LITERAL1
+kDaikin64OffTimeEnableBit LITERAL1
+kDaikin64OffTimeHalfHourBit LITERAL1
+kDaikin64OffTimeOffset LITERAL1
+kDaikin64OffTimeSize LITERAL1
+kDaikin64OnTimeEnableBit LITERAL1
+kDaikin64OnTimeHalfHourBit LITERAL1
+kDaikin64OnTimeOffset LITERAL1
+kDaikin64OnTimeSize LITERAL1
+kDaikin64OneSpace LITERAL1
+kDaikin64Overhead LITERAL1
+kDaikin64PowerToggleBit LITERAL1
+kDaikin64SleepBit LITERAL1
+kDaikin64SwingVBit LITERAL1
+kDaikin64TempOffset LITERAL1
+kDaikin64TempSize LITERAL1
+kDaikin64ZeroSpace LITERAL1
kDaikinAuto LITERAL1
kDaikinBeepLoud LITERAL1
kDaikinBeepOff LITERAL1
@@ -1955,12 +2053,67 @@ kHighNibble LITERAL1
kHighStr LITERAL1
kHighest LITERAL1
kHighestStr LITERAL1
+kHitachiAc1Auto LITERAL1
kHitachiAc1Bits LITERAL1
+kHitachiAc1ChecksumStartByte LITERAL1
+kHitachiAc1Cool LITERAL1
+kHitachiAc1Dry LITERAL1
+kHitachiAc1Fan LITERAL1
+kHitachiAc1FanAuto LITERAL1
+kHitachiAc1FanByte LITERAL1
+kHitachiAc1FanHigh LITERAL1
+kHitachiAc1FanLow LITERAL1
+kHitachiAc1FanMed LITERAL1
+kHitachiAc1FanOffset LITERAL1
+kHitachiAc1FanSize LITERAL1
kHitachiAc1HdrMark LITERAL1
kHitachiAc1HdrSpace LITERAL1
+kHitachiAc1Heat LITERAL1
+kHitachiAc1ModeByte LITERAL1
+kHitachiAc1ModeOffset LITERAL1
+kHitachiAc1ModeSize LITERAL1
+kHitachiAc1ModelByte LITERAL1
+kHitachiAc1ModelOffset LITERAL1
+kHitachiAc1ModelSize LITERAL1
+kHitachiAc1Model_A LITERAL1
+kHitachiAc1Model_B LITERAL1
+kHitachiAc1OffTimerHighByte LITERAL1
+kHitachiAc1OffTimerLowByte LITERAL1
+kHitachiAc1OnTimerHighByte LITERAL1
+kHitachiAc1OnTimerLowByte LITERAL1
+kHitachiAc1PowerByte LITERAL1
+kHitachiAc1PowerOffset LITERAL1
+kHitachiAc1PowerToggleOffset LITERAL1
+kHitachiAc1Sleep1 LITERAL1
+kHitachiAc1Sleep2 LITERAL1
+kHitachiAc1Sleep3 LITERAL1
+kHitachiAc1Sleep4 LITERAL1
+kHitachiAc1SleepByte LITERAL1
+kHitachiAc1SleepOff LITERAL1
+kHitachiAc1SleepOffset LITERAL1
+kHitachiAc1SleepSize LITERAL1
kHitachiAc1StateLength LITERAL1
+kHitachiAc1SwingByte LITERAL1
+kHitachiAc1SwingHOffset LITERAL1
+kHitachiAc1SwingToggleOffset LITERAL1
+kHitachiAc1SwingVOffset LITERAL1
+kHitachiAc1TempAuto LITERAL1
+kHitachiAc1TempByte LITERAL1
+kHitachiAc1TempDelta LITERAL1
+kHitachiAc1TempOffset LITERAL1
+kHitachiAc1TempSize LITERAL1
+kHitachiAc1TimerSize LITERAL1
kHitachiAc2Bits LITERAL1
kHitachiAc2StateLength LITERAL1
+kHitachiAc3BitMark LITERAL1
+kHitachiAc3Bits LITERAL1
+kHitachiAc3HdrMark LITERAL1
+kHitachiAc3HdrSpace LITERAL1
+kHitachiAc3MinBits LITERAL1
+kHitachiAc3MinStateLength LITERAL1
+kHitachiAc3OneSpace LITERAL1
+kHitachiAc3StateLength LITERAL1
+kHitachiAc3ZeroSpace LITERAL1
kHitachiAc424BitMark LITERAL1
kHitachiAc424Bits LITERAL1
kHitachiAc424ButtonByte LITERAL1
@@ -2709,6 +2862,7 @@ kPioneerZeroSpaceTicks LITERAL1
kPowerStr LITERAL1
kPowerToggleStr LITERAL1
kPowerfulStr LITERAL1
+kPreviousPowerStr LITERAL1
kProntoDataOffset LITERAL1
kProntoFreqFactor LITERAL1
kProntoFreqOffset LITERAL1
@@ -2770,12 +2924,14 @@ kRightMaxStr LITERAL1
kRightStr LITERAL1
kRoomStr LITERAL1
kSamsung36Bits LITERAL1
-kSamsungACSectionLength LITERAL1
kSamsungAcAuto LITERAL1
kSamsungAcAutoTemp LITERAL1
kSamsungAcBeepOffset LITERAL1
kSamsungAcBitMark LITERAL1
kSamsungAcBits LITERAL1
+kSamsungAcBreezeOffset LITERAL1
+kSamsungAcBreezeOn LITERAL1
+kSamsungAcBreezeSize LITERAL1
kSamsungAcClean10Offset LITERAL1
kSamsungAcClean11Offset LITERAL1
kSamsungAcCool LITERAL1
@@ -2806,11 +2962,13 @@ kSamsungAcPower6Offset LITERAL1
kSamsungAcPower6Size LITERAL1
kSamsungAcPowerSection LITERAL1
kSamsungAcPowerful10Offset LITERAL1
+kSamsungAcPowerful10On LITERAL1
kSamsungAcPowerful10Size LITERAL1
kSamsungAcPowerfulMask8 LITERAL1
kSamsungAcQuiet1Offset LITERAL1
kSamsungAcQuiet5Offset LITERAL1
kSamsungAcSectionGap LITERAL1
+kSamsungAcSectionLength LITERAL1
kSamsungAcSectionMark LITERAL1
kSamsungAcSectionSpace LITERAL1
kSamsungAcSections LITERAL1
@@ -2864,14 +3022,17 @@ kSensorStr LITERAL1
kSensorTempStr LITERAL1
kSetStr LITERAL1
kSharpAcAuto LITERAL1
-kSharpAcBitFanManualOffset LITERAL1
kSharpAcBitMark LITERAL1
-kSharpAcBitModeNonAutoOffset LITERAL1
kSharpAcBitPowerOffset LITERAL1
-kSharpAcBitTempManualOffset LITERAL1
+kSharpAcBitPreviousPowerOffset LITERAL1
kSharpAcBits LITERAL1
+kSharpAcButtonFan LITERAL1
+kSharpAcButtonOffset LITERAL1
+kSharpAcButtonPowerMode LITERAL1
+kSharpAcButtonSize LITERAL1
+kSharpAcButtonTemp LITERAL1
+kSharpAcByteButton LITERAL1
kSharpAcByteFan LITERAL1
-kSharpAcByteManual LITERAL1
kSharpAcByteMode LITERAL1
kSharpAcBytePower LITERAL1
kSharpAcByteTemp LITERAL1
@@ -2952,6 +3113,14 @@ kSwingStr LITERAL1
kSwingVModeStr LITERAL1
kSwingVStr LITERAL1
kSwingVToggleStr LITERAL1
+kSymphonyBits LITERAL1
+kSymphonyDefaultRepeat LITERAL1
+kSymphonyFooterGap LITERAL1
+kSymphonyFooterMark LITERAL1
+kSymphonyOneMark LITERAL1
+kSymphonyOneSpace LITERAL1
+kSymphonyZeroMark LITERAL1
+kSymphonyZeroSpace LITERAL1
kTcl112AcAuto LITERAL1
kTcl112AcBitEconoOffset LITERAL1
kTcl112AcBitHealthOffset LITERAL1
diff --git a/lib/IRremoteESP8266-2.7.4/library.json b/lib/IRremoteESP8266-2.7.5/library.json
similarity index 97%
rename from lib/IRremoteESP8266-2.7.4/library.json
rename to lib/IRremoteESP8266-2.7.5/library.json
index f135c19e7..3220f9bd2 100644
--- a/lib/IRremoteESP8266-2.7.4/library.json
+++ b/lib/IRremoteESP8266-2.7.5/library.json
@@ -1,6 +1,6 @@
{
"name": "IRremoteESP8266",
- "version": "2.7.4",
+ "version": "2.7.5",
"keywords": "infrared, ir, remote, esp8266, esp32",
"description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)",
"repository":
diff --git a/lib/IRremoteESP8266-2.7.4/library.properties b/lib/IRremoteESP8266-2.7.5/library.properties
similarity index 97%
rename from lib/IRremoteESP8266-2.7.4/library.properties
rename to lib/IRremoteESP8266-2.7.5/library.properties
index e98cd3f3b..16d4c2d20 100644
--- a/lib/IRremoteESP8266-2.7.4/library.properties
+++ b/lib/IRremoteESP8266-2.7.5/library.properties
@@ -1,5 +1,5 @@
name=IRremoteESP8266
-version=2.7.4
+version=2.7.5
author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff
maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto
sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32)
diff --git a/lib/IRremoteESP8266-2.7.4/pylintrc b/lib/IRremoteESP8266-2.7.5/pylintrc
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/pylintrc
rename to lib/IRremoteESP8266-2.7.5/pylintrc
diff --git a/lib/IRremoteESP8266-2.7.4/src/CPPLINT.cfg b/lib/IRremoteESP8266-2.7.5/src/CPPLINT.cfg
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/CPPLINT.cfg
rename to lib/IRremoteESP8266-2.7.5/src/CPPLINT.cfg
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRac.cpp b/lib/IRremoteESP8266-2.7.5/src/IRac.cpp
similarity index 94%
rename from lib/IRremoteESP8266-2.7.4/src/IRac.cpp
rename to lib/IRremoteESP8266-2.7.5/src/IRac.cpp
index d3be30b80..abf450df9 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRac.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/IRac.cpp
@@ -123,6 +123,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#if SEND_DAIKIN216
case decode_type_t::DAIKIN216:
#endif
+#if SEND_DAIKIN64
+ case decode_type_t::DAIKIN64:
+#endif
#if SEND_ELECTRA_AC
case decode_type_t::ELECTRA_AC:
#endif
@@ -144,6 +147,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#if SEND_HITACHI_AC
case decode_type_t::HITACHI_AC:
#endif
+#if SEND_HITACHI_AC1
+ case decode_type_t::HITACHI_AC1:
+#endif
#if SEND_HITACHI_AC424
case decode_type_t::HITACHI_AC424:
#endif
@@ -461,6 +467,27 @@ void IRac::daikin216(IRDaikin216 *ac,
}
#endif // SEND_DAIKIN216
+#if SEND_DAIKIN64
+void IRac::daikin64(IRDaikin64 *ac,
+ const bool on, const stdAc::opmode_t mode,
+ const float degrees, const stdAc::fanspeed_t fan,
+ const stdAc::swingv_t swingv,
+ const bool quiet, const bool turbo,
+ const int16_t sleep, const int16_t clock) {
+ ac->begin();
+ ac->setPowerToggle(on);
+ ac->setMode(ac->convertMode(mode));
+ ac->setTemp(degrees);
+ ac->setFan(ac->convertFan(fan));
+ ac->setSwingVertical((int8_t)swingv >= 0);
+ ac->setTurbo(turbo);
+ ac->setQuiet(quiet);
+ ac->setSleep(sleep >= 0);
+ ac->setClock(clock);
+ ac->send();
+}
+#endif // SEND_DAIKIN64
+
#if SEND_ELECTRA_AC
void IRac::electra(IRElectraAc *ac,
const bool on, const stdAc::opmode_t mode,
@@ -674,6 +701,37 @@ void IRac::hitachi(IRHitachiAc *ac,
}
#endif // SEND_HITACHI_AC
+#if SEND_HITACHI_AC1
+void IRac::hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model,
+ const bool on, const bool power_toggle,
+ const stdAc::opmode_t mode,
+ const float degrees, const stdAc::fanspeed_t fan,
+ const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+ const bool swing_toggle, const int16_t sleep) {
+ ac->begin();
+ ac->setModel(model);
+ ac->setPower(on);
+ ac->setPowerToggle(power_toggle);
+ ac->setMode(ac->convertMode(mode));
+ ac->setTemp(degrees);
+ ac->setFan(ac->convertFan(fan));
+ ac->setSwingV(swingv != stdAc::swingv_t::kOff);
+ ac->setSwingH(swingh != stdAc::swingh_t::kOff);
+ ac->setSwingToggle(swing_toggle);
+ ac->setSleep((sleep >= 0) ? kHitachiAc1Sleep2 : kHitachiAc1SleepOff);
+ // No Sleep setting available.
+ // No Swing(H) setting available.
+ // No Quiet setting available.
+ // No Turbo setting available.
+ // No Light setting available.
+ // No Filter setting available.
+ // No Clean setting available.
+ // No Beep setting available.
+ // No Clock setting available.
+ ac->send();
+}
+#endif // SEND_HITACHI_AC1
+
#if SEND_HITACHI_AC424
void IRac::hitachi424(IRHitachiAc424 *ac,
const bool on, const stdAc::opmode_t mode,
@@ -999,10 +1057,11 @@ void IRac::samsung(IRSamsungAc *ac,
#if SEND_SHARP_AC
void IRac::sharp(IRSharpAc *ac,
- const bool on, const stdAc::opmode_t mode,
+ const bool on, const bool prev_power,
+ const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan) {
ac->begin();
- ac->setPower(on);
+ ac->setPower(on, prev_power);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
@@ -1233,6 +1292,7 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired,
else
result.swingv = stdAc::swingv_t::kOff; // No change, so no toggle.
break;
+ case decode_type_t::DAIKIN64:
case decode_type_t::WHIRLPOOL_AC:
result.power = desired.power ^ prev->power;
break;
@@ -1390,6 +1450,15 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
break;
}
#endif // SEND_DAIKIN216
+#if SEND_DAIKIN64
+ case DAIKIN64:
+ {
+ IRDaikin64 ac(_pin, _inverted, _modulation);
+ daikin64(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
+ send.quiet, send.turbo, send.sleep, send.clock);
+ break;
+ }
+#endif // SEND_DAIKIN64
#if SEND_ELECTRA_AC
case ELECTRA_AC:
{
@@ -1457,6 +1526,23 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
break;
}
#endif // SEND_HITACHI_AC
+#if SEND_HITACHI_AC1
+ case HITACHI_AC1:
+ {
+ IRHitachiAc1 ac(_pin, _inverted, _modulation);
+ bool power_toggle = false;
+ bool swing_toggle = false;
+ if (prev != NULL) {
+ power_toggle = (send.power != prev->power);
+ swing_toggle = (send.swingv != prev->swingv) ||
+ (send.swingh != prev->swingh);
+ }
+ hitachi1(&ac, (hitachi_ac1_remote_model_t)send.model, send.power,
+ power_toggle, send.mode, degC, send.fanspeed, send.swingv,
+ send.swingh, swing_toggle, send.sleep);
+ break;
+ }
+#endif // SEND_HITACHI_AC1
#if SEND_HITACHI_AC424
case HITACHI_AC424:
{
@@ -1572,7 +1658,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
case SHARP_AC:
{
IRSharpAc ac(_pin, _inverted, _modulation);
- sharp(&ac, send.power, send.mode, degC, send.fanspeed);
+ bool prev_power = !send.power;
+ if (prev != NULL) prev_power = prev->power;
+ sharp(&ac, send.power, prev_power, send.mode, degC, send.fanspeed);
break;
}
#endif // SEND_SHARP_AC
@@ -1796,6 +1884,11 @@ int16_t IRac::strToModel(const char *str, const int16_t def) {
return gree_ac_remote_model_t::YAW1F;
} else if (!strcasecmp(str, "YBOFB")) {
return gree_ac_remote_model_t::YBOFB;
+ // HitachiAc1 models
+ } else if (!strcasecmp(str, "R-LT0541-HTA-A")) {
+ return hitachi_ac1_remote_model_t::R_LT0541_HTA_A;
+ } else if (!strcasecmp(str, "R-LT0541-HTA-B")) {
+ return hitachi_ac1_remote_model_t::R_LT0541_HTA_B;
// Fujitsu A/C models
} else if (!strcasecmp(str, "ARRAH2E")) {
return fujitsu_ac_remote_model_t::ARRAH2E;
@@ -2008,6 +2101,13 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_DAIKIN216
+#if DECODE_DAIKIN64
+ case decode_type_t::DAIKIN64: {
+ IRDaikin64 ac(kGpioUnused);
+ ac.setRaw(result->value); // Daikin64 uses value instead of state.
+ return ac.toString();
+ }
+#endif // DECODE_DAIKIN216
#if DECODE_ELECTRA_AC
case decode_type_t::ELECTRA_AC: {
IRElectraAc ac(0);
@@ -2157,6 +2257,13 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_HITACHI_AC
+#if DECODE_HITACHI_AC1
+ case decode_type_t::HITACHI_AC1: {
+ IRHitachiAc1 ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_HITACHI_AC1
#if DECODE_HITACHI_AC424
case decode_type_t::HITACHI_AC424: {
IRHitachiAc424 ac(0);
@@ -2305,6 +2412,14 @@ namespace IRAcUtils {
break;
}
#endif // DECODE_DAIKIN216
+#if DECODE_DAIKIN64
+ case decode_type_t::DAIKIN64: {
+ IRDaikin64 ac(kGpioUnused);
+ ac.setRaw(decode->value); // Uses value instead of state.
+ *result = ac.toCommon(prev);
+ break;
+ }
+#endif // DECODE_DAIKIN64
#if DECODE_ELECTRA_AC
case decode_type_t::ELECTRA_AC: {
IRElectraAc ac(kGpioUnused);
@@ -2361,6 +2476,14 @@ namespace IRAcUtils {
break;
}
#endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC2)
+#if DECODE_HITACHI_AC1
+ case decode_type_t::HITACHI_AC1: {
+ IRHitachiAc1 ac(kGpioUnused);
+ ac.setRaw(decode->state);
+ *result = ac.toCommon();
+ break;
+ }
+#endif // DECODE_HITACHI_AC1
#if DECODE_HITACHI_AC424
case decode_type_t::HITACHI_AC424: {
IRHitachiAc424 ac(kGpioUnused);
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRac.h b/lib/IRremoteESP8266-2.7.5/src/IRac.h
similarity index 94%
rename from lib/IRremoteESP8266-2.7.4/src/IRac.h
rename to lib/IRremoteESP8266-2.7.5/src/IRac.h
index f38865e50..02faba36a 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRac.h
+++ b/lib/IRremoteESP8266-2.7.5/src/IRac.h
@@ -166,6 +166,14 @@ void daikin216(IRDaikin216 *ac,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
const bool quiet, const bool turbo);
#endif // SEND_DAIKIN216
+#if SEND_DAIKIN64
+ void daikin64(IRDaikin64 *ac,
+ const bool on, const stdAc::opmode_t mode,
+ const float degrees, const stdAc::fanspeed_t fan,
+ const stdAc::swingv_t swingv,
+ const bool quiet, const bool turbo,
+ const int16_t sleep = -1, const int16_t clock = -1);
+#endif // SEND_DAIKIN64
#if SEND_ELECTRA_AC
void electra(IRElectraAc *ac,
const bool on, const stdAc::opmode_t mode,
@@ -219,6 +227,14 @@ void electra(IRElectraAc *ac,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh);
#endif // SEND_HITACHI_AC
+#if SEND_HITACHI_AC1
+ void hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model,
+ const bool on, const bool power_toggle,
+ const stdAc::opmode_t mode,
+ const float degrees, const stdAc::fanspeed_t fan,
+ const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+ const bool swing_toggle, const int16_t sleep = -1);
+#endif // SEND_HITACHI_AC1
#if SEND_HITACHI_AC424
void hitachi424(IRHitachiAc424 *ac,
const bool on, const stdAc::opmode_t mode,
@@ -308,7 +324,7 @@ void electra(IRElectraAc *ac,
#endif // SEND_SAMSUNG_AC
#if SEND_SHARP_AC
void sharp(IRSharpAc *ac,
- const bool on, const stdAc::opmode_t mode,
+ const bool on, const bool prev_power, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan);
#endif // SEND_SHARP_AC
#if SEND_TCL112AC
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRrecv.cpp b/lib/IRremoteESP8266-2.7.5/src/IRrecv.cpp
similarity index 86%
rename from lib/IRremoteESP8266-2.7.4/src/IRrecv.cpp
rename to lib/IRremoteESP8266-2.7.5/src/IRrecv.cpp
index e629fc218..f59c1248c 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRrecv.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/IRrecv.cpp
@@ -641,10 +641,28 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
if (decodeHaierACYRW02(results, offset)) return true;
#endif
#if DECODE_HITACHI_AC424
- // HitachiAc424 should be checked before HitachiAC & HitachiAC2
+ // HitachiAc424 should be checked before HitachiAC, HitachiAC2,
+ // & HitachiAC184
DPRINTLN("Attempting Hitachi AC 424 decode");
if (decodeHitachiAc424(results, offset, kHitachiAc424Bits)) return true;
-#endif // DECODE_HITACHI_AC2
+#endif // DECODE_HITACHI_AC424
+#if DECODE_MITSUBISHI136
+ // Needs to happen before HitachiAc3 decode.
+ DPRINTLN("Attempting Mitsubishi136 decode");
+ if (decodeMitsubishi136(results, offset)) return true;
+#endif // DECODE_MITSUBISHI136
+#if DECODE_HITACHI_AC3
+ // HitachiAc3 should be checked before HitachiAC & HitachiAC2
+ // Attempt normal before the short version.
+ DPRINTLN("Attempting Hitachi AC3 decode");
+ // Order these in decreasing bit size, as it is more optimal.
+ if (decodeHitachiAc3(results, offset, kHitachiAc3Bits) ||
+ decodeHitachiAc3(results, offset, kHitachiAc3Bits - 4 * 8) ||
+ decodeHitachiAc3(results, offset, kHitachiAc3Bits - 6 * 8) ||
+ decodeHitachiAc3(results, offset, kHitachiAc3MinBits + 2 * 8) ||
+ decodeHitachiAc3(results, offset, kHitachiAc3MinBits))
+ return true;
+#endif // DECODE_HITACHI_AC3
#if DECODE_HITACHI_AC2
// HitachiAC2 should be checked before HitachiAC
DPRINTLN("Attempting Hitachi AC2 decode");
@@ -759,12 +777,20 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
DPRINTLN("Attempting Daikin152 decode");
if (decodeDaikin152(results, offset)) return true;
#endif // DECODE_DAIKIN152
-#if DECODE_MITSUBISHI136
- DPRINTLN("Attempting Mitsubishi136 decode");
- if (decodeMitsubishi136(results, offset)) return true;
-#endif // DECODE_MITSUBISHI136
- }
+#if DECODE_SYMPHONY
+ DPRINTLN("Attempting Symphony decode");
+ if (decodeSymphony(results, offset)) return true;
+#endif // DECODE_SYMPHONY
+#if DECODE_DAIKIN64
+ DPRINTLN("Attempting Daikin64 decode");
+ if (decodeDaikin64(results, offset)) return true;
+#endif // DECODE_DAIKIN64
+#if DECODE_AIRWELL
+ DPRINTLN("Attempting Airwell decode");
+ if (decodeAirwell(results, offset)) return true;
+#endif // DECODE_AIRWELL
// Typically new protocols are added above this line.
+ }
#if DECODE_HASH
// decodeHash returns a hash on any input.
// Thus, it needs to be last in the list.
@@ -1270,4 +1296,166 @@ uint16_t IRrecv::matchGeneric(volatile uint16_t *data_ptr,
zeromark, zerospace, footermark, footerspace, atleast,
tolerance, excess, MSBfirst);
}
+
+// Match & decode a Manchester Code <= 64bit IR message.
+// The data is stored at result_ptr.
+// Values of 0 for hdrmark, hdrspace, footermark, or footerspace mean skip
+// that requirement.
+//
+// Args:
+// data_ptr: A pointer to where we are at in the capture buffer.
+// NOTE: It is assumed to be pointing to a "Mark", not a "Space".
+// result_ptr: A pointer to where to start storing the bits we decoded.
+// remaining: The size of the capture buffer are remaining.
+// nbits: Nr. of data bits we expect.
+// hdrmark: Nr. of uSeconds for the expected header mark signal.
+// hdrspace: Nr. of uSeconds for the expected header space signal.
+// half_period: Nr. of uSeconds for half the clock's period. (1/2 wavelength)
+// footermark: Nr. of uSeconds for the expected footer mark signal.
+// footerspace: Nr. of uSeconds for the expected footer space/gap signal.
+// atleast: Is the match on the footerspace a matchAtLeast or matchSpace?
+// tolerance: Percentage error margin to allow. (Def: kUseDefTol)
+// excess: Nr. of useconds. (Def: kMarkExcess)
+// MSBfirst: Bit order to save the data in. (Def: true)
+// GEThomas: Use G.E. Thomas (true/default) or IEEE 802.3 (false) convention?
+// Returns:
+// A uint16_t: If successful, how many buffer entries were used. Otherwise 0.
+//
+// Ref:
+// https://en.wikipedia.org/wiki/Manchester_code
+// http://ww1.microchip.com/downloads/en/AppNotes/Atmel-9164-Manchester-Coding-Basics_Application-Note.pdf
+uint16_t IRrecv::matchManchester(volatile const uint16_t *data_ptr,
+ uint64_t *result_ptr,
+ const uint16_t remaining,
+ const uint16_t nbits,
+ const uint16_t hdrmark,
+ const uint32_t hdrspace,
+ const uint16_t half_period,
+ const uint16_t footermark,
+ const uint32_t footerspace,
+ const bool atleast,
+ const uint8_t tolerance,
+ const int16_t excess,
+ const bool MSBfirst,
+ const bool GEThomas) {
+ uint16_t offset = 0;
+ uint64_t data = 0;
+ uint16_t nr_of_half_periods = GEThomas;
+ // 2 per bit, and 4 extra for the timing sync.
+ uint16_t expected_half_periods = 2 * nbits + 4;
+ bool currentBit = false;
+
+ // Calculate how much remaining buffer is required.
+ // Shortest case. Longest case is 2 * nbits.
+ uint16_t min_remaining = nbits + 2;
+
+ if (hdrmark) min_remaining++;
+ if (hdrspace) min_remaining++;
+ if (footermark) min_remaining++;
+ // Don't need to extend for footerspace because it could be the end of message
+
+ // Check if there is enough capture buffer to possibly have the message.
+ if (remaining < min_remaining) return 0; // Nope, so abort.
+
+ // Header
+ if (hdrmark && !matchMark(*(data_ptr + offset++), hdrmark, tolerance, excess))
+ return 0;
+ // Manchester Code always has a guaranteed 2x half_period (T2) at the start
+ // of the data section. e.g. a sync header. If it is a GEThomas-style, then
+ // it is space(T);mark(2xT);space(T), thus we need to check for that space
+ // plus any requested "header" space.
+ if ((hdrspace || GEThomas) &&
+ !matchSpace(*(data_ptr + offset++),
+ hdrspace + ((GEThomas) ? half_period : 0), tolerance, excess))
+ return 0;
+
+ // Data
+ // Loop until we find a 'long' pulse. This is the timing sync per protocol.
+ while ((offset < remaining) && (nr_of_half_periods < expected_half_periods) &&
+ !match(*(data_ptr + offset), half_period * 2, tolerance, excess)) {
+ // Was it not a short pulse?
+ if (!match(*(data_ptr + offset), half_period, tolerance, excess))
+ return 0;
+ nr_of_half_periods++;
+ offset++;
+ }
+
+ // Data (cont.)
+
+ // We are now pointing to the first 'long' pulse.
+ // Loop through the buffer till we run out of buffer, or nr of half periods.
+ while (offset < remaining && nr_of_half_periods < expected_half_periods) {
+ // Only if there is enough half_periods left for a long pulse &
+ // Is it a 'long' pulse?
+ if (nr_of_half_periods < expected_half_periods - 1 &&
+ match(*(data_ptr + offset), half_period * 2, tolerance, excess)) {
+ // Yes, so invert the value we will append.
+ currentBit = !currentBit;
+ nr_of_half_periods += 2; // A 'long' pulse is two half periods.
+ offset++;
+ // Append the bit value.
+ data <<= 1;
+ data |= currentBit;
+ } else if (match(*(data_ptr + offset), half_period, tolerance, excess)) {
+ // or is it part of a 'short' pulse pair?
+ nr_of_half_periods++;
+ offset++;
+ // Look for the second half of the 'short' pulse pair.
+ // Do we have enough buffer or nr of half periods?
+ if (offset < remaining && nr_of_half_periods < expected_half_periods) {
+ // We do, so look for it.
+ if (match(*(data_ptr + offset), half_period, tolerance, excess)) {
+ // Found it!
+ nr_of_half_periods++;
+ // No change of the polarity of the bit we will append.
+ // Append the bit value.
+ data <<= 1;
+ data |= currentBit;
+ offset++;
+ } else {
+ // It's not what we expected.
+ return 0;
+ }
+ }
+ } else if (nr_of_half_periods == expected_half_periods - 1 &&
+ matchAtLeast(*(data_ptr + offset), half_period, tolerance,
+ excess)) {
+ // Special case when we are at the end of the expected nr of periods.
+ // i.e. The pulse could be merged with the footer.
+ nr_of_half_periods++;
+ break;
+ } else {
+ // It's neither, so abort.
+ return 0;
+ }
+ }
+ // Did we collect the expected amount of data?
+ if (nr_of_half_periods < expected_half_periods) return 0;
+
+ // Footer
+ if (footermark &&
+ !(matchMark(*(data_ptr + offset), footermark + half_period,
+ tolerance, excess) ||
+ matchMark(*(data_ptr + offset), footermark,
+ tolerance, excess)))
+ return 0;
+ offset++;
+ // If we have something still to match & haven't reached the end of the buffer
+ if (footerspace && offset < remaining) {
+ if (atleast) {
+ if (!matchAtLeast(*(data_ptr + offset), footerspace, tolerance, excess))
+ return 0;
+ } else {
+ if (!matchSpace(*(data_ptr + offset), footerspace, tolerance, excess))
+ return 0;
+ }
+ offset++;
+ }
+
+ // Clean up and process the data.
+ if (!MSBfirst) data = reverseBits(data, nbits);
+ // Trim the data to size to remove timing sync.
+ *result_ptr = GETBITS64(data, 0, nbits);
+ return offset;
+}
// End of IRrecv class -------------------
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRrecv.h b/lib/IRremoteESP8266-2.7.5/src/IRrecv.h
similarity index 93%
rename from lib/IRremoteESP8266-2.7.4/src/IRrecv.h
rename to lib/IRremoteESP8266-2.7.5/src/IRrecv.h
index 60559981c..aeea5b32d 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRrecv.h
+++ b/lib/IRremoteESP8266-2.7.5/src/IRrecv.h
@@ -221,6 +221,20 @@ class IRrecv {
const uint8_t tolerance = kUseDefTol,
const int16_t excess = kMarkExcess,
const bool MSBfirst = true);
+ uint16_t matchManchester(volatile const uint16_t *data_ptr,
+ uint64_t *result_ptr,
+ const uint16_t remaining,
+ const uint16_t nbits,
+ const uint16_t hdrmark,
+ const uint32_t hdrspace,
+ const uint16_t clock_period,
+ const uint16_t footermark,
+ const uint32_t footerspace,
+ const bool atleast = false,
+ const uint8_t tolerance = kUseDefTol,
+ const int16_t excess = kMarkExcess,
+ const bool MSBfirst = true,
+ const bool GEThomas = true);
void crudeNoiseFilter(decode_results *results, const uint16_t floor = 0);
bool decodeHash(decode_results *results);
#if (DECODE_NEC || DECODE_SHERWOOD || DECODE_AIWA_RC_T501 || SEND_SANYO)
@@ -393,6 +407,11 @@ class IRrecv {
const uint16_t nbits = kDaikinBits,
const bool strict = true);
#endif
+#if DECODE_DAIKIN64
+ bool decodeDaikin64(decode_results *results, uint16_t offset = kStartOffset,
+ const uint16_t nbits = kDaikin64Bits,
+ const bool strict = true);
+#endif // DECODE_DAIKIN64
#if DECODE_DAIKIN128
bool decodeDaikin128(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kDaikin128Bits,
@@ -485,6 +504,12 @@ class IRrecv {
const uint16_t nbits = kHitachiAc1Bits,
const bool strict = true);
#endif
+#if DECODE_HITACHI_AC3
+ bool decodeHitachiAc3(decode_results *results,
+ uint16_t offset = kStartOffset,
+ const uint16_t nbits = kHitachiAc3Bits,
+ const bool strict = true);
+#endif // DECODE_HITACHI_AC3
#if DECODE_HITACHI_AC424
bool decodeHitachiAc424(decode_results *results,
uint16_t offset = kStartOffset,
@@ -558,6 +583,16 @@ class IRrecv {
const uint16_t nbits = kEpsonBits,
const bool strict = true);
#endif // DECODE_EPSON
+#if DECODE_SYMPHONY
+ bool decodeSymphony(decode_results *results, uint16_t offset = kStartOffset,
+ const uint16_t nbits = kSymphonyBits,
+ const bool strict = true);
+#endif // DECODE_SYMPHONY
+#if DECODE_AIRWELL
+ bool decodeAirwell(decode_results *results, uint16_t offset = kStartOffset,
+ const uint16_t nbits = kAirwellBits,
+ const bool strict = true);
+#endif // DECODE_AIRWELL
};
#endif // IRRECV_H_
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRremoteESP8266.h b/lib/IRremoteESP8266-2.7.5/src/IRremoteESP8266.h
similarity index 95%
rename from lib/IRremoteESP8266-2.7.4/src/IRremoteESP8266.h
rename to lib/IRremoteESP8266-2.7.5/src/IRremoteESP8266.h
index a048e23fc..dd8008bc0 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRremoteESP8266.h
+++ b/lib/IRremoteESP8266-2.7.5/src/IRremoteESP8266.h
@@ -52,7 +52,7 @@
#endif // UNIT_TEST
// Library Version
-#define _IRREMOTEESP8266_VERSION_ "2.7.4"
+#define _IRREMOTEESP8266_VERSION_ "2.7.5"
// Set the language & locale for the library. See the `locale` dir for options.
#ifndef _IR_LOCALE_
@@ -411,6 +411,20 @@
#define SEND_HITACHI_AC2 _IR_ENABLE_DEFAULT_
#endif // SEND_HITACHI_AC2
+#ifndef DECODE_HITACHI_AC3
+#define DECODE_HITACHI_AC3 _IR_ENABLE_DEFAULT_
+#endif // DECODE_HITACHI_AC3
+#ifndef SEND_HITACHI_AC3
+#define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_
+#endif // SEND_HITACHI_AC3
+
+#ifndef DECODE_HITACHI_AC424
+#define DECODE_HITACHI_AC424 _IR_ENABLE_DEFAULT_
+#endif // DECODE_HITACHI_AC424
+#ifndef SEND_HITACHI_AC424
+#define SEND_HITACHI_AC424 _IR_ENABLE_DEFAULT_
+#endif // SEND_HITACHI_AC424
+
#ifndef DECODE_GICABLE
#define DECODE_GICABLE _IR_ENABLE_DEFAULT_
#endif // DECODE_GICABLE
@@ -558,13 +572,6 @@
#define SEND_DAIKIN152 _IR_ENABLE_DEFAULT_
#endif // SEND_DAIKIN152
-#ifndef DECODE_HITACHI_AC424
-#define DECODE_HITACHI_AC424 _IR_ENABLE_DEFAULT_
-#endif // DECODE_HITACHI_AC424
-#ifndef SEND_HITACHI_AC424
-#define SEND_HITACHI_AC424 _IR_ENABLE_DEFAULT_
-#endif // SEND_HITACHI_AC424
-
#ifndef DECODE_EPSON
#define DECODE_EPSON _IR_ENABLE_DEFAULT_
#endif // DECODE_EPSON
@@ -572,6 +579,27 @@
#define SEND_EPSON _IR_ENABLE_DEFAULT_
#endif // SEND_EPSON
+#ifndef DECODE_SYMPHONY
+#define DECODE_SYMPHONY _IR_ENABLE_DEFAULT_
+#endif // DECODE_SYMPHONY
+#ifndef SEND_SYMPHONY
+#define SEND_SYMPHONY _IR_ENABLE_DEFAULT_
+#endif // SEND_SYMPHONY
+
+#ifndef DECODE_DAIKIN64
+#define DECODE_DAIKIN64 _IR_ENABLE_DEFAULT_
+#endif // DECODE_DAIKIN64
+#ifndef SEND_DAIKIN64
+#define SEND_DAIKIN64 _IR_ENABLE_DEFAULT_
+#endif // SEND_DAIKIN64
+
+#ifndef DECODE_AIRWELL
+#define DECODE_AIRWELL _IR_ENABLE_DEFAULT_
+#endif // DECODE_AIRWELL
+#ifndef SEND_AIRWELL
+#define SEND_AIRWELL _IR_ENABLE_DEFAULT_
+#endif // SEND_AIRWELL
+
#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 || \
@@ -582,7 +610,7 @@
DECODE_DAIKIN216 || DECODE_SHARP_AC || DECODE_DAIKIN160 || \
DECODE_NEOCLIMA || DECODE_DAIKIN176 || DECODE_DAIKIN128 || \
DECODE_AMCOR || DECODE_DAIKIN152 || DECODE_MITSUBISHI136 || \
- DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424)
+ DECODE_MITSUBISHI112 || DECODE_HITACHI_AC424 || DECODE_HITACHI_AC3)
#define DECODE_AC true // We need some common infrastructure for decoding A/Cs.
#else
#define DECODE_AC false // We don't need that infrastructure.
@@ -695,14 +723,20 @@ enum decode_type_t {
HITACHI_AC424,
SONY_38K,
EPSON, // 75
+ SYMPHONY,
+ HITACHI_AC3,
+ DAIKIN64,
+ AIRWELL,
// Add new entries before this one, and update it to point to the last entry.
- kLastDecodeType = EPSON,
+ kLastDecodeType = AIRWELL,
};
// Message lengths & required repeat values
const uint16_t kNoRepeat = 0;
const uint16_t kSingleRepeat = 1;
+const uint16_t kAirwellBits = 32;
+const uint16_t kAirwellMinRepeats = 2;
const uint16_t kAiwaRcT501Bits = 15;
const uint16_t kAiwaRcT501MinRepeats = kSingleRepeat;
const uint16_t kAlokaBits = 32;
@@ -724,6 +758,8 @@ const uint16_t kDaikinDefaultRepeat = kNoRepeat;
const uint16_t kDaikin2StateLength = 39;
const uint16_t kDaikin2Bits = kDaikin2StateLength * 8;
const uint16_t kDaikin2DefaultRepeat = kNoRepeat;
+const uint16_t kDaikin64Bits = 64;
+const uint16_t kDaikin64DefaultRepeat = kNoRepeat;
const uint16_t kDaikin160StateLength = 20;
const uint16_t kDaikin160Bits = kDaikin160StateLength * 8;
const uint16_t kDaikin160DefaultRepeat = kNoRepeat;
@@ -774,6 +810,10 @@ const uint16_t kHitachiAc1StateLength = 13;
const uint16_t kHitachiAc1Bits = kHitachiAc1StateLength * 8;
const uint16_t kHitachiAc2StateLength = 53;
const uint16_t kHitachiAc2Bits = kHitachiAc2StateLength * 8;
+const uint16_t kHitachiAc3StateLength = 27;
+const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8;
+const uint16_t kHitachiAc3MinStateLength = 15;
+const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8;
const uint16_t kHitachiAc424StateLength = 53;
const uint16_t kHitachiAc424Bits = kHitachiAc424StateLength * 8;
const uint16_t kInaxBits = 24;
@@ -857,6 +897,8 @@ const uint16_t kSony15Bits = 15;
const uint16_t kSony20Bits = 20;
const uint16_t kSonyMinBits = 12;
const uint16_t kSonyMinRepeat = 2;
+const uint16_t kSymphonyBits = 11;
+const uint16_t kSymphonyDefaultRepeat = kSingleRepeat;
const uint16_t kTcl112AcStateLength = 14;
const uint16_t kTcl112AcBits = kTcl112AcStateLength * 8;
const uint16_t kTcl112AcDefaultRepeat = kNoRepeat;
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRsend.cpp b/lib/IRremoteESP8266-2.7.5/src/IRsend.cpp
similarity index 86%
rename from lib/IRremoteESP8266-2.7.4/src/IRsend.cpp
rename to lib/IRremoteESP8266-2.7.5/src/IRsend.cpp
index 8bc12949b..bb5f55407 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRsend.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/IRsend.cpp
@@ -462,6 +462,105 @@ void IRsend::sendGeneric(const uint16_t headermark, const uint32_t headerspace,
}
}
+// Generic method for sending Manchester code data.
+// Will send leading or trailing 0's if the nbits is larger than the number
+// of bits in data.
+//
+// Args:
+// half_period: Nr. of uSeconds for half the clock's period. (1/2 wavelength)
+// data: The data to be transmitted.
+// nbits: Nr. of bits of data to be sent.
+// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order.
+// GEThomas: Use G.E. Thomas (true/default) or IEEE 802.3 (false).
+void IRsend::sendManchesterData(const uint16_t half_period,
+ const uint64_t data,
+ const uint16_t nbits, const bool MSBfirst,
+ const bool GEThomas) {
+ if (nbits == 0) return; // Nothing to send.
+ uint16_t bits = nbits;
+ uint64_t copy = (GEThomas) ? data : ~data;
+
+ if (MSBfirst) { // Send the MSB first.
+ // Send 0's until we get down to a bit size we can actually manage.
+ if (bits > (sizeof(data) * 8)) {
+ sendManchesterData(half_period, 0ULL, bits - sizeof(data) * 8, MSBfirst,
+ GEThomas);
+ bits = sizeof(data) * 8;
+ }
+ // Send the supplied data.
+ for (uint64_t mask = 1ULL << (bits - 1); mask; mask >>= 1)
+ if (copy & mask) {
+ mark(half_period);
+ space(half_period);
+ } else {
+ space(half_period);
+ mark(half_period);
+ }
+ } else { // Send the Least Significant Bit (LSB) first / MSB last.
+ for (bits = 0; bits < nbits; bits++, copy >>= 1)
+ if (copy & 1) {
+ mark(half_period);
+ space(half_period);
+ } else {
+ space(half_period);
+ mark(half_period);
+ }
+ }
+}
+
+// Generic method for sending Manchester code messages.
+// Will send leading or trailing 0's if the nbits is larger than the number
+// of bits in data.
+//
+// Args:
+// headermark: Nr. of usecs for the led to be pulsed for the header mark.
+// A value of 0 means no header mark.
+// headerspace: Nr. of usecs for the led to be off after the header mark.
+// A value of 0 means no header space.
+// half_period: Nr. of uSeconds for half the clock's period. (1/2 wavelength)
+// footermark: Nr. of usecs for the led to be pulsed for the footer mark.
+// A value of 0 means no footer mark.
+// gap: Min. nr. of usecs for the led to be off after the footer mark.
+// This is effectively the absolute minimum gap between messages.
+// data: The data to be transmitted.
+// nbits: Nr. of bits of data to be sent.
+// frequency: The frequency we want to modulate at.
+// Assumes < 1000 means kHz otherwise it is in Hz.
+// Most common value is 38000 or 38, for 38kHz.
+// MSBfirst: Flag for bit transmission order. Defaults to MSB->LSB order.
+// repeat: Nr. of extra times the message will be sent.
+// e.g. 0 = 1 message sent, 1 = 1 initial + 1 repeat = 2 messages
+// dutycycle: Percentage duty cycle of the LED.
+// e.g. 25 = 25% = 1/4 on, 3/4 off.
+// If you are not sure, try 50 percent.
+// GEThomas: Use G.E. Thomas (true/default) or IEEE 802.3 (false).
+void IRsend::sendManchester(const uint16_t headermark,
+ const uint32_t headerspace,
+ const uint16_t half_period,
+ const uint16_t footermark, const uint32_t gap,
+ const uint64_t data, const uint16_t nbits,
+ const uint16_t frequency, const bool MSBfirst,
+ const uint16_t repeat, const uint8_t dutycycle,
+ const bool GEThomas) {
+ // Setup
+ enableIROut(frequency, dutycycle);
+
+ // We always send a message, even for repeat=0, hence '<= repeat'.
+ for (uint16_t r = 0; r <= repeat; r++) {
+ // Header
+ if (headermark) mark(headermark);
+ if (headerspace) space(headerspace);
+ // Data Marker/sync
+ // This guarantees a double width half_period. i.e. a Period or T2.
+ sendManchesterData(half_period, 0b01, 2, true, GEThomas);
+ // Data
+ sendManchesterData(half_period, data, nbits, MSBfirst, GEThomas);
+ // Footer
+ if (footermark) mark(footermark);
+ if (gap) space(gap);
+ }
+}
+
#if SEND_RAW
// Send a raw IRremote message.
//
@@ -509,17 +608,20 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) {
case MITSUBISHI2:
case MITSUBISHI_AC:
case SHERWOOD:
+ case SYMPHONY:
case TOSHIBA_AC:
return kSingleRepeat;
// Special
+ case AIRWELL:
+ return kAirwellMinRepeats;
case DISH:
return kDishMinRepeat;
+ case EPSON:
+ return kEpsonMinRepeat;
case SONY:
return kSonyMinRepeat;
case SONY_38K:
return kSonyMinRepeat + 1;
- case EPSON:
- return kEpsonMinRepeat;
default:
return kNoRepeat;
}
@@ -532,6 +634,8 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) {
// int16_t: The number of bits.
uint16_t IRsend::defaultBits(const decode_type_t protocol) {
switch (protocol) {
+ case SYMPHONY:
+ return 11;
case RC5:
return 12;
case LASERTAG:
@@ -560,6 +664,7 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
case LG:
case LG2:
return 28;
+ case AIRWELL:
case CARRIER_AC:
case EPSON:
case NEC:
@@ -601,6 +706,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
return kDaikin2Bits;
case DAIKIN216:
return kDaikin216Bits;
+ case DAIKIN64:
+ return kDaikin64Bits;
case ELECTRA_AC:
return kElectraAcBits;
case GREE:
@@ -615,6 +722,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
return kHitachiAc1Bits;
case HITACHI_AC2:
return kHitachiAc2Bits;
+ case HITACHI_AC3:
+ return kHitachiAc3Bits;
case HITACHI_AC424:
return kHitachiAc424Bits;
case KELVINATOR:
@@ -666,6 +775,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data,
const uint16_t nbits, const uint16_t repeat) {
uint16_t min_repeat = std::max(IRsend::minRepeats(type), repeat);
switch (type) {
+#if SEND_AIRWELL
+ case AIRWELL:
+ sendAirwell(data, nbits, min_repeat);
+ break;
+#endif
#if SEND_AIWA_RC_T501
case AIWA_RC_T501:
sendAiwaRCT501(data, nbits, min_repeat);
@@ -681,6 +795,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data,
sendCOOLIX(data, nbits, min_repeat);
break;
#endif
+#if SEND_DAIKIN64
+ case DAIKIN64:
+ sendDaikin64(data, nbits, min_repeat);
+ break;
+#endif
#if SEND_DENON
case DENON:
sendDenon(data, nbits, min_repeat);
@@ -834,6 +953,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data,
sendSony38(data, nbits, min_repeat);
break;
#endif
+#if SEND_SYMPHONY
+ case SYMPHONY:
+ sendSymphony(data, nbits, min_repeat);
+ break;
+#endif
#if SEND_TECO
case TECO:
sendTeco(data, nbits, min_repeat);
@@ -951,6 +1075,11 @@ bool IRsend::send(const decode_type_t type, const unsigned char *state,
sendHitachiAC2(state, nbytes);
break;
#endif // SEND_HITACHI_AC2
+#if SEND_HITACHI_AC3
+ case HITACHI_AC3:
+ sendHitachiAc3(state, nbytes);
+ break;
+#endif // SEND_HITACHI_AC3
#if SEND_HITACHI_AC424
case HITACHI_AC424:
sendHitachiAc424(state, nbytes);
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRsend.h b/lib/IRremoteESP8266-2.7.5/src/IRsend.h
similarity index 92%
rename from lib/IRremoteESP8266-2.7.4/src/IRsend.h
rename to lib/IRremoteESP8266-2.7.5/src/IRsend.h
index 902f22010..8d5e6a862 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRsend.h
+++ b/lib/IRremoteESP8266-2.7.5/src/IRsend.h
@@ -126,6 +126,11 @@ enum gree_ac_remote_model_t {
YBOFB, // (2) Green, YBOFB2, YAPOF3
};
+enum hitachi_ac1_remote_model_t {
+ R_LT0541_HTA_A = 1, // (1) R-LT0541-HTA Remote in "A" setting. (Default)
+ R_LT0541_HTA_B, // (2) R-LT0541-HTA Remote in "B" setting.
+};
+
enum panasonic_ac_remote_model_t {
kPanasonicUnknown = 0,
kPanasonicLke = 1,
@@ -162,6 +167,17 @@ class IRsend {
void sendData(uint16_t onemark, uint32_t onespace, uint16_t zeromark,
uint32_t zerospace, uint64_t data, uint16_t nbits,
bool MSBfirst = true);
+ void sendManchesterData(const uint16_t half_period, const uint64_t data,
+ const uint16_t nbits, const bool MSBfirst = true,
+ const bool GEThomas = true);
+ void sendManchester(const uint16_t headermark, const uint32_t headerspace,
+ const uint16_t half_period, const uint16_t footermark,
+ const uint32_t gap, const uint64_t data,
+ const uint16_t nbits, const uint16_t frequency = 38,
+ const bool MSBfirst = true,
+ const uint16_t repeat = kNoRepeat,
+ const uint8_t dutycycle = kDutyDefault,
+ const bool GEThomas = true);
void sendGeneric(const uint16_t headermark, const uint32_t headerspace,
const uint16_t onemark, const uint32_t onespace,
const uint16_t zeromark, const uint32_t zerospace,
@@ -362,6 +378,10 @@ class IRsend {
const uint16_t nbytes = kDaikinStateLength,
const uint16_t repeat = kDaikinDefaultRepeat);
#endif
+#if SEND_DAIKIN64
+ void sendDaikin64(const uint64_t data, const uint16_t nbits = kDaikin64Bits,
+ const uint16_t repeat = kDaikin64DefaultRepeat);
+#endif // SEND_DAIKIN64
#if SEND_DAIKIN128
void sendDaikin128(const unsigned char data[],
const uint16_t nbytes = kDaikin128StateLength,
@@ -471,6 +491,12 @@ class IRsend {
const uint16_t nbytes = kHitachiAc2StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat);
#endif
+#if SEND_HITACHI_AC3
+ void sendHitachiAc3(const unsigned char data[],
+ const uint16_t nbytes, // No default as there as so many
+ // different sizes
+ const uint16_t repeat = kHitachiAcDefaultRepeat);
+#endif // SEND_HITACHI_AC3
#if SEND_HITACHI_AC424
void sendHitachiAc424(const unsigned char data[],
const uint16_t nbytes = kHitachiAc424StateLength,
@@ -539,6 +565,14 @@ class IRsend {
void sendEpson(uint64_t data, uint16_t nbits = kEpsonBits,
uint16_t repeat = kEpsonMinRepeat);
#endif
+#if SEND_SYMPHONY
+ void sendSymphony(uint64_t data, uint16_t nbits = kSymphonyBits,
+ uint16_t repeat = kSymphonyDefaultRepeat);
+#endif
+#if SEND_AIRWELL
+ void sendAirwell(uint64_t data, uint16_t nbits = kAirwellBits,
+ uint16_t repeat = kAirwellMinRepeats);
+#endif
protected:
#ifdef UNIT_TEST
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRtext.cpp b/lib/IRremoteESP8266-2.7.5/src/IRtext.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/IRtext.cpp
rename to lib/IRremoteESP8266-2.7.5/src/IRtext.cpp
index 82f728191..72ddd45b7 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRtext.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/IRtext.cpp
@@ -130,6 +130,7 @@ const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO;
const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE;
const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET;
const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE;
+const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER;
const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP;
const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER;
const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE;
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRtext.h b/lib/IRremoteESP8266-2.7.5/src/IRtext.h
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/IRtext.h
rename to lib/IRremoteESP8266-2.7.5/src/IRtext.h
index 522b528bc..13d2d400c 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRtext.h
+++ b/lib/IRremoteESP8266-2.7.5/src/IRtext.h
@@ -104,6 +104,7 @@ extern const char* kOutsideStr;
extern const char* kPowerfulStr;
extern const char* kPowerStr;
extern const char* kPowerToggleStr;
+extern const char* kPreviousPowerStr;
extern const char* kProtocolStr;
extern const char* kPurifyStr;
extern const char* kQuietStr;
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRtimer.cpp b/lib/IRremoteESP8266-2.7.5/src/IRtimer.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/IRtimer.cpp
rename to lib/IRremoteESP8266-2.7.5/src/IRtimer.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRtimer.h b/lib/IRremoteESP8266-2.7.5/src/IRtimer.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/IRtimer.h
rename to lib/IRremoteESP8266-2.7.5/src/IRtimer.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRutils.cpp b/lib/IRremoteESP8266-2.7.5/src/IRutils.cpp
similarity index 97%
rename from lib/IRremoteESP8266-2.7.4/src/IRutils.cpp
rename to lib/IRremoteESP8266-2.7.5/src/IRutils.cpp
index 230b24809..db9095143 100644
--- a/lib/IRremoteESP8266-2.7.4/src/IRutils.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/IRutils.cpp
@@ -95,6 +95,8 @@ decode_type_t strToDecodeType(const char * const str) {
return decode_type_t::UNKNOWN;
else if (!strcasecmp(str, "UNUSED"))
return decode_type_t::UNUSED;
+ else if (!strcasecmp(str, "AIRWELL"))
+ return decode_type_t::AIRWELL;
else if (!strcasecmp(str, "AIWA_RC_T501"))
return decode_type_t::AIWA_RC_T501;
else if (!strcasecmp(str, "AMCOR"))
@@ -119,6 +121,8 @@ decode_type_t strToDecodeType(const char * const str) {
return decode_type_t::DAIKIN2;
else if (!strcasecmp(str, "DAIKIN216"))
return decode_type_t::DAIKIN216;
+ else if (!strcasecmp(str, "DAIKIN64"))
+ return decode_type_t::DAIKIN64;
else if (!strcasecmp(str, "DENON"))
return decode_type_t::DENON;
else if (!strcasecmp(str, "DISH"))
@@ -147,6 +151,8 @@ decode_type_t strToDecodeType(const char * const str) {
return decode_type_t::HITACHI_AC1;
else if (!strcasecmp(str, "HITACHI_AC2"))
return decode_type_t::HITACHI_AC2;
+ else if (!strcasecmp(str, "HITACHI_AC3"))
+ return decode_type_t::HITACHI_AC3;
else if (!strcasecmp(str, "HITACHI_AC424"))
return decode_type_t::HITACHI_AC424;
else if (!strcasecmp(str, "INAX"))
@@ -232,6 +238,8 @@ decode_type_t strToDecodeType(const char * const str) {
return decode_type_t::SONY;
else if (!strcasecmp(str, "SONY_38K"))
return decode_type_t::SONY_38K;
+ else if (!strcasecmp(str, "SYMPHONY"))
+ return decode_type_t::SYMPHONY;
else if (!strcasecmp(str, "TCL112AC"))
return decode_type_t::TCL112AC;
else if (!strcasecmp(str, "TECO"))
@@ -267,6 +275,9 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) {
case UNUSED:
result = F("UNUSED");
break;
+ case AIRWELL:
+ result = F("AIRWELL");
+ break;
case AIWA_RC_T501:
result = F("AIWA_RC_T501");
break;
@@ -303,6 +314,9 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) {
case DAIKIN216:
result = F("DAIKIN216");
break;
+ case DAIKIN64:
+ result = F("DAIKIN64");
+ break;
case DENON:
result = F("DENON");
break;
@@ -345,6 +359,9 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) {
case HITACHI_AC2:
result = F("HITACHI_AC2");
break;
+ case HITACHI_AC3:
+ result = F("HITACHI_AC3");
+ break;
case HITACHI_AC424:
result = F("HITACHI_AC424");
break;
@@ -471,6 +488,9 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) {
case SONY_38K:
result = F("SONY_38K");
break;
+ case SYMPHONY:
+ result = F("SYMPHONY");
+ break;
case TCL112AC:
result = F("TCL112AC");
break;
@@ -525,6 +545,7 @@ bool hasACState(const decode_type_t protocol) {
case HITACHI_AC:
case HITACHI_AC1:
case HITACHI_AC2:
+ case HITACHI_AC3:
case HITACHI_AC424:
case KELVINATOR:
case MITSUBISHI136:
@@ -851,6 +872,15 @@ namespace irutils {
default: return kUnknownStr;
}
break;
+ case decode_type_t::HITACHI_AC1:
+ switch (model) {
+ case hitachi_ac1_remote_model_t::R_LT0541_HTA_A:
+ return F("R-LT0541-HTA-A");
+ case hitachi_ac1_remote_model_t::R_LT0541_HTA_B:
+ return F("R-LT0541-HTA-B");
+ default: return kUnknownStr;
+ }
+ break;
case decode_type_t::LG:
case decode_type_t::LG2:
switch (model) {
diff --git a/lib/IRremoteESP8266-2.7.4/src/IRutils.h b/lib/IRremoteESP8266-2.7.5/src/IRutils.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/IRutils.h
rename to lib/IRremoteESP8266-2.7.5/src/IRutils.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/i18n.h b/lib/IRremoteESP8266-2.7.5/src/i18n.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/i18n.h
rename to lib/IRremoteESP8266-2.7.5/src/i18n.h
diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Airwell.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Airwell.cpp
new file mode 100644
index 000000000..5eb103b84
--- /dev/null
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Airwell.cpp
@@ -0,0 +1,83 @@
+// Copyright 2020 David Conran
+
+#include "IRrecv.h"
+#include "IRsend.h"
+
+// Airwell "Manchester code" based protocol.
+// Some other Airwell products use the COOLIX protocol.
+//
+// Supports:
+// Brand: Airwell, Model: RC08W remote
+
+const uint8_t kAirwellOverhead = 4;
+const uint16_t kAirwellHalfClockPeriod = 950; // uSeconds
+const uint16_t kAirwellHdrMark = 3 * kAirwellHalfClockPeriod; // uSeconds
+const uint16_t kAirwellHdrSpace = 4 * kAirwellHalfClockPeriod; // uSeconds
+const uint16_t kAirwellFooterMark = 5 * kAirwellHalfClockPeriod; // uSeconds
+
+#if SEND_AIRWELL
+// Send an Airwell Manchester Code formatted message.
+//
+// Args:
+// data: The message to be sent.
+// nbits: The number of bits of the message to be sent.
+// Typically kAirwellBits.
+// repeat: The number of times the command is to be repeated.
+//
+// Status: BETA / Appears to be working.
+//
+// Ref:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+void IRsend::sendAirwell(uint64_t data, uint16_t nbits, uint16_t repeat) {
+ // Header + Data
+ sendManchester(kAirwellHdrMark, kAirwellHdrMark, kAirwellHalfClockPeriod,
+ 0, 0, data, nbits, 38000, true, repeat);
+ // Footer
+ mark(kAirwellHdrMark + kAirwellHalfClockPeriod);
+ space(kDefaultMessageGap); // A guess.
+}
+#endif
+
+#if DECODE_AIRWELL
+// Decode the supplied Airwell "Manchester code" message.
+//
+// Args:
+// results: Ptr to the data to decode and where to store the decode result.
+// offset: The starting index to use when attempting to decode the raw data.
+// Typically/Defaults to kStartOffset.
+// nbits: The number of data bits to expect. Typically kAirwellBits.
+// 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 be working.
+//
+// Ref:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+bool IRrecv::decodeAirwell(decode_results *results, uint16_t offset,
+ const uint16_t nbits, const bool strict) {
+ if (results->rawlen < nbits + kAirwellOverhead - offset)
+ return false; // Too short a message to match.
+
+ // Compliance
+ if (strict && nbits != kAirwellBits)
+ return false; // Doesn't match our protocol defn.
+
+ // Header #1 + Data #1 + Footer #1 (There are total of 3 sections)
+ uint16_t used = matchManchester(results->rawbuf + offset, &results->value,
+ results->rawlen - offset, nbits,
+ kAirwellHdrMark, kAirwellHdrMark,
+ kAirwellHalfClockPeriod,
+ kAirwellHdrMark, kAirwellHdrSpace,
+ true);
+ if (used == 0) return false;
+ offset += used;
+
+ // Success
+ results->decode_type = decode_type_t::AIRWELL;
+ results->bits = nbits;
+ results->address = 0;
+ results->command = 0;
+ return true;
+}
+#endif
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Aiwa.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Aiwa.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Aiwa.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Aiwa.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Amcor.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Amcor.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Amcor.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Amcor.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Amcor.h b/lib/IRremoteESP8266-2.7.5/src/ir_Amcor.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Amcor.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Amcor.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Argo.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Argo.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Argo.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Argo.cpp
index 11e8336e3..0c4656cb5 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Argo.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Argo.cpp
@@ -38,7 +38,7 @@ using irutils::setBits;
// Args:
// data: An array of kArgoStateLength bytes containing the IR command.
//
-// Status: ALPHA / Untested.
+// Status: BETA / Probably works.
void IRsend::sendArgo(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) {
@@ -385,7 +385,7 @@ String IRArgoAC::toString(void) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: ALPHA / Probably doesn't work.
+// Status: BETA / Probably works.
//
// Note:
// This decoder is based soley off sendArgo(). We have no actual captures
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Argo.h b/lib/IRremoteESP8266-2.7.5/src/ir_Argo.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Argo.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Argo.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Carrier.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Carrier.cpp
similarity index 97%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Carrier.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Carrier.cpp
index 7b2b00d58..293711a03 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Carrier.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Carrier.cpp
@@ -30,7 +30,7 @@ const uint16_t kCarrierAcGap = 20000;
// nbits: The bit size of the message being sent. typically kCarrierAcBits.
// repeat: The number of times the message is to be repeated.
//
-// Status: BETA / Appears to work on real devices.
+// Status: STABLE / Work on real devices.
//
void IRsend::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) {
for (uint16_t r = 0; r <= repeat; r++) {
@@ -61,7 +61,7 @@ void IRsend::sendCarrierAC(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: ALPHA / Untested.
+// Status: BETA / Probably works.
//
bool IRrecv::decodeCarrierAC(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Coolix.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Coolix.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Coolix.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Coolix.cpp
index a8d98301c..65535442a 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Coolix.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Coolix.cpp
@@ -586,7 +586,7 @@ String IRCoolixAC::toString(void) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Probably working.
+// Status: STABLE / Known Working.
bool IRrecv::decodeCOOLIX(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
// The protocol sends the data normal + inverted, alternating on
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Coolix.h b/lib/IRremoteESP8266-2.7.5/src/ir_Coolix.h
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Coolix.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Coolix.h
index c2fb2034d..6f7778416 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Coolix.h
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Coolix.h
@@ -23,6 +23,7 @@
// Brand: Midea, Model: MS12FU-10HRDN1-QRD0GW(B) A/C
// Brand: Midea, Model: MSABAU-07HRFN1-QRD0GW A/C (circa 2016)
// Brand: Tokio, Model: AATOEMF17-12CHR1SW split-type RG51|50/BGE Remote
+// Brand: Airwell, Model: RC08B remote
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/484
// Kudos:
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Daikin.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Daikin.cpp
similarity index 88%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Daikin.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Daikin.cpp
index 4941fe977..c18e77569 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Daikin.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Daikin.cpp
@@ -593,7 +593,7 @@ bool IRrecv::decodeDaikin(decode_results *results, uint16_t offset,
// Args:
// data: An array of kDaikin2StateLength bytes containing the IR command.
//
-// Status: BETA/Appears to work.
+// Status: STABLE / Expected to work.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/582
@@ -1219,7 +1219,7 @@ String IRDaikin2::toString(void) {
// - Daikin FTXZ25NV1B, FTXZ35NV1B, FTXZ50NV1B Aircon
// - Daikin ARC477A1 remote
//
-// Status: BETA / Work as expected.
+// Status: STABLE / Works as expected.
//
// Ref:
// https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/tree/master/IRremote
@@ -1565,7 +1565,7 @@ String IRDaikin216::toString(void) {
// Supported devices:
// - Daikin ARC433B69 remote.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Should be working.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/689
@@ -2283,7 +2283,7 @@ String IRDaikin176::toString(void) {
// Supported devices:
// - Daikin BRC4C153 remote.
//
-// Status: BETA / Probably works.
+// Status: STABLE / Expected to work.
//
bool IRrecv::decodeDaikin176(decode_results *results, uint16_t offset,
@@ -3187,3 +3187,420 @@ String IRDaikin152::toString(void) {
result += addBoolToString(getComfort(), kComfortStr);
return result;
}
+
+#if SEND_DAIKIN64
+// Send a Daikin 64 bit A/C message.
+//
+// Args:
+// data: A uint64_t containing the IR command/code.
+//
+// Supported devices:
+// - Daikin FFN-C.
+//
+// Status: Beta / Probably Working.
+//
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1064
+void IRsend::sendDaikin64(const uint64_t data, const uint16_t nbits,
+ const uint16_t repeat) {
+ enableIROut(kDaikin64Freq);
+ for (uint16_t r = 0; r <= repeat; r++) {
+ for (uint8_t i = 0; i < 2; i++) {
+ // Leader
+ mark(kDaikin64LdrMark);
+ space(kDaikin64LdrSpace);
+ }
+ // Header + Data + Footer #1
+ sendGeneric(kDaikin64HdrMark, kDaikin64HdrSpace,
+ kDaikin64BitMark, kDaikin64OneSpace,
+ kDaikin64BitMark, kDaikin64ZeroSpace,
+ kDaikin64BitMark, kDaikin64Gap,
+ data, nbits, kDaikin64Freq, false, 0, 50);
+ // Footer #2
+ mark(kDaikin64HdrMark);
+ space(kDefaultMessageGap); // A guess of the gap between messages.
+ }
+}
+#endif // SEND_DAIKIN64
+
+#if DECODE_DAIKIN64
+// Decode the supplied Daikin 64 bit A/C message.
+// Args:
+// results: Ptr to the data to decode and where to store the decode result.
+// offset: The starting index to use when attempting to decode the raw data.
+// Typically/Defaults to kStartOffset.
+// nbits: Nr. of bits to expect in the data portion. (kDaikin64Bits)
+// strict: Flag to indicate if we strictly adhere to the specification.
+// Returns:
+// boolean: True if it can decode it, false if it can't.
+//
+// Supported devices:
+// - Daikin FFN-C.
+//
+// Status: Beta / Probably Working.
+//
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1064
+bool IRrecv::decodeDaikin64(decode_results *results, uint16_t offset,
+ const uint16_t nbits, const bool strict) {
+ if (results->rawlen < 2 * nbits + kDaikin64Overhead - offset)
+ return false; // Too short a message to match.
+ // Compliance
+ if (strict && nbits != kDaikin64Bits)
+ return false;
+
+ // Leader
+ for (uint8_t i = 0; i < 2; i++) {
+ if (!matchMark(results->rawbuf[offset++], kDaikin64LdrMark))
+ return false;
+ if (!matchSpace(results->rawbuf[offset++], kDaikin64LdrSpace))
+ return false;
+ }
+ // Header + Data + Footer #1
+ uint16_t used = matchGeneric(results->rawbuf + offset, &results->value,
+ results->rawlen - offset, nbits,
+ kDaikin64HdrMark, kDaikin64HdrSpace,
+ kDaikin64BitMark, kDaikin64OneSpace,
+ kDaikin64BitMark, kDaikin64ZeroSpace,
+ kDaikin64BitMark, kDaikin64Gap,
+ false, _tolerance, kMarkExcess, false);
+ if (used == 0) return false;
+ offset += used;
+ // Footer #2
+ if (!matchMark(results->rawbuf[offset++], kDaikin64HdrMark))
+ return false;
+
+ // Compliance
+ if (strict && !IRDaikin64::validChecksum(results->value)) return false;
+ // Success
+ results->decode_type = decode_type_t::DAIKIN64;
+ results->bits = nbits;
+ results->command = 0;
+ results->address = 0;
+ return true;
+}
+#endif // DAIKIN64
+
+// Class for handling Daikin 64 bit / 19 byte A/C messages.
+//
+// Code by crankyoldgit.
+//
+// Supported Remotes: Daikin ARC480A5 remote
+//
+// Ref:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/873
+// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.cpp
+// https://github.com/ToniA/arduino-heatpumpir/blob/master/DaikinHeatpumpARC480A14IR.h
+IRDaikin64::IRDaikin64(const uint16_t pin, const bool inverted,
+ const bool use_modulation)
+ : _irsend(pin, inverted, use_modulation) { stateReset(); }
+
+void IRDaikin64::begin(void) { _irsend.begin(); }
+
+#if SEND_DAIKIN64
+void IRDaikin64::send(const uint16_t repeat) {
+ _irsend.sendDaikin64(getRaw(), kDaikin64Bits, repeat);
+}
+#endif // SEND_DAIKIN64
+
+// Calc the checksum for a given state.
+// Args:
+// state: The value to calc the checksum of.
+// Returns:
+// A 4-bit checksum stored in a uint_8.
+uint8_t IRDaikin64::calcChecksum(const uint64_t state) {
+ uint64_t data = GETBITS64(state, 0, kDaikin64ChecksumOffset);
+ uint8_t result = 0;
+ for (; data; data >>= 4) // Add each nibble together.
+ result += GETBITS64(data, 0, 4);
+ return result & 0xF;
+}
+
+// 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 IRDaikin64::validChecksum(const uint64_t state) {
+ // Validate the checksum of the given state.
+ return (GETBITS64(state, kDaikin64ChecksumOffset,
+ kDaikin64ChecksumSize) == calcChecksum(state));
+}
+
+// Calculate and set the checksum values for the internal state.
+void IRDaikin64::checksum(void) {
+ setBits(&remote_state, kDaikin64ChecksumOffset, kDaikin64ChecksumSize,
+ calcChecksum(remote_state));
+}
+
+void IRDaikin64::stateReset(void) {
+ remote_state = kDaikin64KnownGoodState;
+}
+
+uint64_t IRDaikin64::getRaw(void) {
+ checksum(); // Ensure correct settings before sending.
+ return remote_state;
+}
+
+void IRDaikin64::setRaw(const uint64_t new_state) { remote_state = new_state; }
+
+void IRDaikin64::setPowerToggle(const bool on) {
+ setBit(&remote_state, kDaikin64PowerToggleBit, on);
+}
+
+bool IRDaikin64::getPowerToggle(void) {
+ return GETBIT64(remote_state, kDaikin64PowerToggleBit);
+}
+
+// Set the temp in deg C
+void IRDaikin64::setTemp(const uint8_t temp) {
+ uint8_t degrees = std::max(temp, kDaikin64MinTemp);
+ degrees = std::min(degrees, kDaikin64MaxTemp);
+ setBits(&remote_state, kDaikin64TempOffset,
+ kDaikin64TempSize, uint8ToBcd(degrees));
+}
+
+uint8_t IRDaikin64::getTemp(void) {
+ return bcdToUint8(GETBITS64(remote_state, kDaikin64TempOffset,
+ kDaikin64TempSize));
+}
+
+uint8_t IRDaikin64::getMode(void) {
+ return GETBITS64(remote_state, kDaikin64ModeOffset, kDaikin64ModeSize);
+}
+
+void IRDaikin64::setMode(const uint8_t mode) {
+ switch (mode) {
+ case kDaikin64Fan:
+ case kDaikin64Dry:
+ case kDaikin64Cool:
+ break;
+ default:
+ this->setMode(kDaikin64Cool);
+ return;
+ }
+ setBits(&remote_state, kDaikin64ModeOffset, kDaikin64ModeSize, mode);
+}
+
+// Convert a standard A/C mode into its native mode.
+uint8_t IRDaikin64::convertMode(const stdAc::opmode_t mode) {
+ switch (mode) {
+ case stdAc::opmode_t::kDry: return kDaikin64Dry;
+ case stdAc::opmode_t::kFan: return kDaikin64Fan;
+ default: return kDaikinCool;
+ }
+}
+
+// Convert a native mode to it's common equivalent.
+stdAc::opmode_t IRDaikin64::toCommonMode(const uint8_t mode) {
+ switch (mode) {
+ case kDaikin64Cool: return stdAc::opmode_t::kCool;
+ case kDaikin64Dry: return stdAc::opmode_t::kDry;
+ case kDaikin64Fan: return stdAc::opmode_t::kFan;
+ default: return stdAc::opmode_t::kAuto;
+ }
+}
+
+uint8_t IRDaikin64::getFan(void) {
+ return GETBITS64(remote_state, kDaikin64FanOffset, kDaikin64FanSize);
+}
+
+void IRDaikin64::setFan(const uint8_t speed) {
+ switch (speed) {
+ case kDaikin64FanQuiet:
+ case kDaikin64FanTurbo:
+ case kDaikin64FanAuto:
+ case kDaikin64FanHigh:
+ case kDaikin64FanMed:
+ case kDaikin64FanLow:
+ setBits(&remote_state, kDaikin64FanOffset, kDaikin64FanSize, speed);
+ break;
+ default:
+ this->setFan(kDaikin64FanAuto);
+ }
+}
+
+// Convert a standard A/C Fan speed into its native fan speed.
+uint8_t IRDaikin64::convertFan(const stdAc::fanspeed_t speed) {
+ switch (speed) {
+ case stdAc::fanspeed_t::kMin: return kDaikin64FanQuiet;
+ case stdAc::fanspeed_t::kLow: return kDaikin64FanLow;
+ case stdAc::fanspeed_t::kMedium: return kDaikin64FanMed;
+ case stdAc::fanspeed_t::kHigh: return kDaikin64FanHigh;
+ case stdAc::fanspeed_t::kMax: return kDaikin64FanTurbo;
+ default: return kDaikin64FanAuto;
+ }
+}
+
+// Convert a native fan speed to it's common equivalent.
+stdAc::fanspeed_t IRDaikin64::toCommonFanSpeed(const uint8_t speed) {
+ switch (speed) {
+ case kDaikin64FanTurbo: return stdAc::fanspeed_t::kMax;
+ case kDaikin64FanHigh: return stdAc::fanspeed_t::kHigh;
+ case kDaikin64FanMed: return stdAc::fanspeed_t::kMedium;
+ case kDaikin64FanLow: return stdAc::fanspeed_t::kLow;
+ case kDaikinFanQuiet: return stdAc::fanspeed_t::kMin;
+ default: return stdAc::fanspeed_t::kAuto;
+ }
+}
+
+bool IRDaikin64::getTurbo(void) {
+ return getFan() == kDaikin64FanTurbo;
+}
+
+void IRDaikin64::setTurbo(const bool on) {
+ if (on) {
+ setFan(kDaikin64FanTurbo);
+ } else {
+ if (getFan() == kDaikin64FanTurbo) setFan(kDaikin64FanAuto);
+ }
+}
+
+bool IRDaikin64::getQuiet(void) {
+ return getFan() == kDaikin64FanQuiet;
+}
+
+void IRDaikin64::setQuiet(const bool on) {
+ if (on) {
+ setFan(kDaikin64FanQuiet);
+ } else {
+ if (getFan() == kDaikin64FanQuiet) setFan(kDaikin64FanAuto);
+ }
+}
+
+void IRDaikin64::setSwingVertical(const bool on) {
+ setBit(&remote_state, kDaikin64SwingVBit, on);
+}
+
+bool IRDaikin64::getSwingVertical(void) {
+ return GETBIT64(remote_state, kDaikin64SwingVBit);
+}
+
+void IRDaikin64::setSleep(const bool on) {
+ setBit(&remote_state, kDaikin64SleepBit, on);
+}
+
+bool IRDaikin64::getSleep(void) {
+ return GETBIT64(remote_state, kDaikin64SleepBit);
+}
+
+void IRDaikin64::setClock(const uint16_t mins_since_midnight) {
+ uint16_t mins = mins_since_midnight;
+ if (mins_since_midnight >= 24 * 60) mins = 0; // Bounds check.
+ setBits(&remote_state, kDaikin64ClockOffset, kDaikin64ClockMinsSize,
+ uint8ToBcd(mins % 60)); // Mins
+ setBits(&remote_state, kDaikin64ClockOffset + kDaikin64ClockMinsSize,
+ kDaikin64ClockHoursSize, uint8ToBcd(mins / 60)); // Hours
+}
+
+uint16_t IRDaikin64::getClock(void) {
+ return bcdToUint8(GETBITS64(remote_state,
+ kDaikin64ClockOffset + kDaikin64ClockMinsSize,
+ kDaikin64ClockHoursSize)) * 60 +
+ bcdToUint8(GETBITS64(remote_state, kDaikin64ClockOffset,
+ kDaikin64ClockMinsSize));
+}
+
+void IRDaikin64::setOnTimeEnabled(const bool on) {
+ setBit(&remote_state, kDaikin64OnTimeEnableBit, on);
+}
+
+bool IRDaikin64::getOnTimeEnabled(void) {
+ return GETBIT64(remote_state, kDaikin64OnTimeEnableBit);
+}
+
+uint16_t IRDaikin64::getOnTime(void) {
+ return bcdToUint8(GETBITS64(remote_state, kDaikin64OnTimeOffset,
+ kDaikin64OnTimeSize)) * 60 +
+ (GETBIT64(remote_state, kDaikin64OnTimeHalfHourBit) ? 30 : 0);
+}
+
+void IRDaikin64::setOnTime(const uint16_t mins_since_midnight) {
+ uint16_t halfhours = mins_since_midnight / 30;
+ if (mins_since_midnight >= 24 * 60) halfhours = 0; // Bounds check.
+ setBits(&remote_state, kDaikin64OnTimeOffset, kDaikin64OnTimeSize,
+ uint8ToBcd(halfhours / 2)); // Hours
+ // Half Hour
+ setBit(&remote_state, kDaikin64OnTimeHalfHourBit, halfhours % 2);
+}
+
+void IRDaikin64::setOffTimeEnabled(const bool on) {
+ setBit(&remote_state, kDaikin64OffTimeEnableBit, on);
+}
+
+bool IRDaikin64::getOffTimeEnabled(void) {
+ return GETBIT64(remote_state, kDaikin64OffTimeEnableBit);
+}
+
+uint16_t IRDaikin64::getOffTime(void) {
+ return bcdToUint8(GETBITS64(remote_state, kDaikin64OffTimeOffset,
+ kDaikin64OffTimeSize)) * 60 +
+ (GETBIT64(remote_state, kDaikin64OffTimeHalfHourBit) ? 30 : 0);
+}
+
+void IRDaikin64::setOffTime(const uint16_t mins_since_midnight) {
+ uint16_t halfhours = mins_since_midnight / 30;
+ if (mins_since_midnight >= 24 * 60) halfhours = 0; // Bounds check.
+ setBits(&remote_state, kDaikin64OffTimeOffset, kDaikin64OffTimeSize,
+ uint8ToBcd(halfhours / 2)); // Hours
+ // Half Hour
+ setBit(&remote_state, kDaikin64OffTimeHalfHourBit, halfhours % 2);
+}
+
+// Convert the internal state into a human readable string.
+String IRDaikin64::toString(void) {
+ String result = "";
+ result.reserve(120); // Reserve some heap for the string to reduce fragging.
+ result += addBoolToString(getPowerToggle(), kPowerToggleStr, false);
+ result += addModeToString(getMode(), 0xFF, kDaikin64Cool,
+ 0xFF, kDaikin64Dry, kDaikin64Fan);
+ result += addTempToString(getTemp());
+ if (!getTurbo()) {
+ result += addFanToString(getFan(), kDaikin64FanHigh, kDaikin64FanLow,
+ kDaikin64FanAuto, kDaikin64FanQuiet,
+ kDaikin64FanMed);
+ } else {
+ result += addIntToString(getFan(), kFanStr);
+ result += kSpaceLBraceStr;
+ result += kTurboStr;
+ result += ')';
+ }
+ result += addBoolToString(getTurbo(), kTurboStr);
+ result += addBoolToString(getQuiet(), kQuietStr);
+ result += addBoolToString(getSwingVertical(), kSwingVStr);
+ result += addBoolToString(getSleep(), kSleepStr);
+ result += addLabeledString(minsToString(getClock()), kClockStr);
+ result += addLabeledString(getOnTimeEnabled()
+ ? minsToString(getOnTime()) : kOffStr,
+ kOnTimerStr);
+ result += addLabeledString(getOffTimeEnabled()
+ ? minsToString(getOffTime()) : kOffStr,
+ kOffTimerStr);
+ return result;
+}
+
+// Convert the A/C state to it's common equivalent.
+stdAc::state_t IRDaikin64::toCommon(const stdAc::state_t *prev) {
+ stdAc::state_t result;
+ if (prev != NULL) result = *prev;
+ result.protocol = decode_type_t::DAIKIN64;
+ result.model = -1; // No models used.
+ result.power ^= getPowerToggle();
+ result.mode = toCommonMode(getMode());
+ result.celsius = true;
+ result.degrees = getTemp();
+ result.fanspeed = toCommonFanSpeed(getFan());
+ result.swingv = getSwingVertical() ? stdAc::swingv_t::kAuto
+ : stdAc::swingv_t::kOff;
+ result.turbo = getTurbo();
+ result.quiet = getQuiet();
+ result.sleep = getSleep() ? 0 : -1;
+ result.clock = getClock();
+ // Not supported.
+ result.swingh = stdAc::swingh_t::kOff;
+ result.clean = false;
+ result.filter = false;
+ result.beep = false;
+ result.econo = false;
+ result.light = false;
+ return result;
+}
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Daikin.h b/lib/IRremoteESP8266-2.7.5/src/ir_Daikin.h
similarity index 87%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Daikin.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Daikin.h
index 42039b07b..3630aa77b 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Daikin.h
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Daikin.h
@@ -17,6 +17,8 @@
// Brand: Daikin, Model: FTXB09AXVJU A/C (DAIKIN128)
// Brand: Daikin, Model: BRC52B63 remote (DAIKIN128)
// Brand: Daikin, Model: ARC480A5 remote (DAIKIN152)
+// Brand: Daikin, Model: FFN-C/FCN-F Series A/C (DAIKIN64)
+// Brand: Daikin, Model: DGS01 remote (DAIKIN64)
#ifndef IR_DAIKIN_H_
#define IR_DAIKIN_H_
@@ -430,6 +432,56 @@ const uint8_t kDaikin152ComfortOffset = 1; // Mask 0b00000010
const uint8_t kDaikin152SensorByte = kDaikin152EconoByte; // Mask 0b00001000
const uint8_t kDaikin152SensorOffset = 3; // Mask 0b00001000
+const uint16_t kDaikin64HdrMark = kDaikin128HdrMark;
+const uint16_t kDaikin64BitMark = kDaikin128BitMark;
+const uint16_t kDaikin64HdrSpace = kDaikin128HdrSpace;
+const uint16_t kDaikin64OneSpace = kDaikin128OneSpace;
+const uint16_t kDaikin64ZeroSpace = kDaikin128ZeroSpace;
+const uint16_t kDaikin64LdrMark = kDaikin128LeaderMark;
+const uint16_t kDaikin64Gap = kDaikin128Gap;
+const uint16_t kDaikin64LdrSpace = kDaikin128LeaderSpace;
+const uint16_t kDaikin64Freq = kDaikin128Freq; // Hz.
+const uint16_t kDaikin64Overhead = 9;
+
+const uint64_t kDaikin64KnownGoodState = 0x7C16161607204216;
+const uint8_t kDaikin64ModeOffset = 8;
+const uint8_t kDaikin64ModeSize = 4; // Mask 0b111100000000
+const uint8_t kDaikin64Dry = 0b001;
+const uint8_t kDaikin64Cool = 0b010;
+const uint8_t kDaikin64Fan = 0b100;
+const uint8_t kDaikin64FanOffset = kDaikin64ModeOffset + kDaikin64ModeSize;
+const uint8_t kDaikin64FanSize = 4; // Mask 0b1111000000000000
+const uint8_t kDaikin64FanAuto = 0b0001;
+const uint8_t kDaikin64FanLow = 0b1000;
+const uint8_t kDaikin64FanMed = 0b0100;
+const uint8_t kDaikin64FanHigh = 0b0010;
+const uint8_t kDaikin64FanQuiet = 0b1001;
+const uint8_t kDaikin64FanTurbo = 0b0011;
+const uint8_t kDaikin64ClockOffset = kDaikin64FanOffset + kDaikin64FanSize;
+const uint8_t kDaikin64ClockMinsSize = 8;
+const uint8_t kDaikin64ClockHoursSize = 8;
+const uint8_t kDaikin64ClockSize = kDaikin64ClockMinsSize +
+ kDaikin64ClockHoursSize; // Mask 0b1111111111111111 << 15
+const uint8_t kDaikin64OnTimeOffset = kDaikin64ClockOffset +
+ kDaikin64ClockSize;
+const uint8_t kDaikin64OnTimeSize = 6;
+const uint8_t kDaikin64OnTimeHalfHourBit = kDaikin64OnTimeOffset +
+ kDaikin64OnTimeSize;
+const uint8_t kDaikin64OnTimeEnableBit = kDaikin64OnTimeHalfHourBit + 1;
+const uint8_t kDaikin64OffTimeOffset = kDaikin64OnTimeEnableBit + 1;
+const uint8_t kDaikin64OffTimeSize = 6;
+const uint8_t kDaikin64OffTimeHalfHourBit = kDaikin64OffTimeOffset +
+ kDaikin64OffTimeSize;
+const uint8_t kDaikin64OffTimeEnableBit = kDaikin64OffTimeHalfHourBit + 1;
+const uint8_t kDaikin64TempOffset = 48;
+const uint8_t kDaikin64TempSize = 8; // Mask 0b11111111 << 47
+const uint8_t kDaikin64MinTemp = 16; // Celsius
+const uint8_t kDaikin64MaxTemp = 30; // Celsius
+const uint8_t kDaikin64SwingVBit = 56;
+const uint8_t kDaikin64SleepBit = kDaikin64SwingVBit + 1;
+const uint8_t kDaikin64PowerToggleBit = 59;
+const uint8_t kDaikin64ChecksumOffset = 60;
+const uint8_t kDaikin64ChecksumSize = 4; // Mask 0b1111 << 59
// Legacy defines.
#define DAIKIN_COOL kDaikinCool
@@ -881,4 +933,63 @@ class IRDaikin152 {
void stateReset();
void checksum();
};
+
+// Class to emulate a Daikin DGS01 remote.
+class IRDaikin64 {
+ public:
+ explicit IRDaikin64(const uint16_t pin, const bool inverted = false,
+ const bool use_modulation = true);
+
+#if SEND_DAIKIN64
+ void send(const uint16_t repeat = kDaikin64DefaultRepeat);
+ uint8_t calibrate(void) { return _irsend.calibrate(); }
+#endif // SEND_DAIKIN64
+ void begin();
+ uint64_t getRaw();
+ void setRaw(const uint64_t new_state);
+ static uint8_t calcChecksum(const uint64_t state);
+ static bool validChecksum(const uint64_t state);
+ void setPowerToggle(const bool on);
+ bool getPowerToggle(void);
+ void setTemp(const uint8_t temp);
+ uint8_t getTemp();
+ void setFan(const uint8_t fan);
+ uint8_t getFan(void);
+ void setMode(const uint8_t mode);
+ uint8_t getMode(void);
+ void setSwingVertical(const bool on);
+ bool getSwingVertical(void);
+ void setSleep(const bool on);
+ bool getSleep(void);
+ bool getQuiet(void);
+ void setQuiet(const bool on);
+ bool getTurbo(void);
+ void setTurbo(const bool on);
+ void setClock(const uint16_t mins_since_midnight);
+ uint16_t getClock(void);
+ void setOnTimeEnabled(const bool on);
+ bool getOnTimeEnabled(void);
+ void setOnTime(const uint16_t mins_since_midnight);
+ uint16_t getOnTime(void);
+ void setOffTimeEnabled(const bool on);
+ bool getOffTimeEnabled(void);
+ void setOffTime(const uint16_t mins_since_midnight);
+ uint16_t getOffTime(void);
+ static uint8_t convertMode(const stdAc::opmode_t mode);
+ static uint8_t convertFan(const stdAc::fanspeed_t speed);
+ static stdAc::opmode_t toCommonMode(const uint8_t mode);
+ static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ stdAc::state_t toCommon(const stdAc::state_t *prev = NULL);
+ String toString(void);
+#ifndef UNIT_TEST
+
+ private:
+ IRsend _irsend;
+#else
+ IRsendTest _irsend;
+#endif
+ uint64_t remote_state;
+ void stateReset();
+ void checksum();
+};
#endif // IR_DAIKIN_H_
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Denon.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Denon.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Denon.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Denon.cpp
index bd4940714..6dd4cd839 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Denon.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Denon.cpp
@@ -40,7 +40,7 @@ const uint64_t kDenonManufacturer = 0x2A4CULL;
// nbits: Nr. of bits of data to be sent. Typically kDenonBits.
// repeat: Nr. of additional times the message is to be sent.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Should be working.
//
// Notes:
// Some Denon devices use a Kaseikyo/Panasonic 48-bit format
@@ -71,7 +71,7 @@ void IRsend::sendDenon(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Should work fine.
+// Status: STABLE / Should work fine.
//
// Ref:
// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Denon.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Dish.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Dish.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Dish.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Dish.cpp
index 834ceda04..291201ed6 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Dish.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Dish.cpp
@@ -37,7 +37,7 @@ const uint16_t kDishRptSpace = kDishRptSpaceTicks * kDishTick;
// nbits: The bit size of the command being sent.
// repeat: The number of times you want the command to be repeated.
//
-// Status: BETA / Previously working.
+// Status: STABLE / Working.
//
// Note:
// Dishplayer is a different protocol.
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Electra.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Electra.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Electra.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Electra.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Electra.h b/lib/IRremoteESP8266-2.7.5/src/ir_Electra.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Electra.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Electra.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Epson.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Epson.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Epson.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Epson.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Fujitsu.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Fujitsu.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Fujitsu.h b/lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Fujitsu.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Fujitsu.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_GICable.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_GICable.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_GICable.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_GICable.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_GlobalCache.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_GlobalCache.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_GlobalCache.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_GlobalCache.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Goodweather.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Goodweather.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.cpp
index 8b7e0b76e..97a4a9277 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Goodweather.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.cpp
@@ -34,7 +34,7 @@ using irutils::setBits;
// nbits: Nr. of bits of data in the message. (Default is kGoodweatherBits)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
-// Status: ALPHA / Untested.
+// Status: BETA / Needs testing on real device.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/697
@@ -377,7 +377,7 @@ String IRGoodweatherAc::toString(void) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: ALPHA / Untested.
+// Status: BETA / Probably works.
bool IRrecv::decodeGoodweather(decode_results* results, uint16_t offset,
const uint16_t nbits,
const bool strict) {
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Goodweather.h b/lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Goodweather.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Goodweather.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Gree.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Gree.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Gree.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Gree.cpp
index 735e3b88c..81062d650 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Gree.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Gree.cpp
@@ -50,7 +50,7 @@ using irutils::setBits;
// nbytes: Nr. of bytes of data in the array. (>=kGreeStateLength)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
-// Status: ALPHA / Untested.
+// Status: STABLE / Working.
//
// Ref:
// https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp
@@ -84,7 +84,7 @@ void IRsend::sendGree(const unsigned char data[], const uint16_t nbytes,
// nbits: Nr. of bits of data in the message. (Default is kGreeBits)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
-// Status: ALPHA / Untested.
+// Status: STABLE / Working.
//
// Ref:
// https://github.com/ToniA/arduino-heatpumpir/blob/master/GreeHeatpumpIR.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Gree.h b/lib/IRremoteESP8266-2.7.5/src/ir_Gree.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Gree.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Gree.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Haier.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Haier.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Haier.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Haier.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Haier.h b/lib/IRremoteESP8266-2.7.5/src/ir_Haier.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Haier.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Haier.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Hitachi.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.cpp
similarity index 60%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Hitachi.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.cpp
index 02489d010..01cc49d28 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Hitachi.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.cpp
@@ -37,12 +37,22 @@ const uint16_t kHitachiAc424BitMark = 463;
const uint16_t kHitachiAc424OneSpace = 1208;
const uint16_t kHitachiAc424ZeroSpace = 372;
+// Support for HitachiAc3 protocol
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1060
+const uint16_t kHitachiAc3HdrMark = 3400; // Header
+const uint16_t kHitachiAc3HdrSpace = 1660; // Header
+const uint16_t kHitachiAc3BitMark = 460;
+const uint16_t kHitachiAc3OneSpace = 1250;
+const uint16_t kHitachiAc3ZeroSpace = 410;
+
using irutils::addBoolToString;
using irutils::addIntToString;
using irutils::addLabeledString;
using irutils::addModeToString;
+using irutils::addModelToString;
using irutils::addFanToString;
using irutils::addTempToString;
+using irutils::minsToString;
using irutils::setBit;
using irutils::setBits;
@@ -54,7 +64,7 @@ using irutils::setBits;
// nbytes: Nr. of bytes of data in the array. (>=kHitachiAcStateLength)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
-// Status: ALPHA / Untested.
+// Status: STABLE / Working.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/417
@@ -80,7 +90,7 @@ void IRsend::sendHitachiAC(const unsigned char data[], const uint16_t nbytes,
// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc1StateLength)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
-// Status: BETA / Appears to work.
+// Status: STABLE / Confirmed Working.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/453
@@ -107,7 +117,7 @@ void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes,
// nbytes: Nr. of bytes of data in the array. (>=kHitachiAc2StateLength)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
-// Status: BETA / Appears to work.
+// Status: STABLE / Expected to work.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/417
@@ -354,6 +364,358 @@ String IRHitachiAc::toString(void) {
return result;
}
+// Class for handling the remote control on a Hitachi 13 byte A/C message.
+// Ref:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1056
+
+IRHitachiAc1::IRHitachiAc1(const uint16_t pin, const bool inverted,
+ const bool use_modulation)
+ : _irsend(pin, inverted, use_modulation) { stateReset(); }
+
+void IRHitachiAc1::stateReset(void) {
+ for (uint8_t i = 0; i < kHitachiAc1StateLength; i++) remote_state[i] = 0x00;
+ // Copy in a known good state.
+ remote_state[0] = 0xB2;
+ remote_state[1] = 0xAE;
+ remote_state[2] = 0x4D;
+ remote_state[3] = 0x91;
+ remote_state[4] = 0xF0;
+ remote_state[5] = 0xE1;
+ remote_state[6] = 0xA4;
+ remote_state[11] = 0x61;
+ remote_state[12] = 0x24;
+}
+
+void IRHitachiAc1::begin(void) { _irsend.begin(); }
+
+uint8_t IRHitachiAc1::calcChecksum(const uint8_t state[],
+ const uint16_t length) {
+ uint8_t sum = 0;
+ for (uint16_t i = kHitachiAc1ChecksumStartByte; i < length - 1; i++) {
+ sum += reverseBits(GETBITS8(state[i], kLowNibble, kNibbleSize),
+ kNibbleSize);
+ sum += reverseBits(GETBITS8(state[i], kHighNibble, kNibbleSize),
+ kNibbleSize);
+ }
+ return reverseBits(sum, 8);
+}
+
+void IRHitachiAc1::checksum(const uint16_t length) {
+ remote_state[length - 1] = calcChecksum(remote_state, length);
+}
+
+bool IRHitachiAc1::validChecksum(const uint8_t state[], const uint16_t length) {
+ if (length < 2) return true; // Assume true for lengths that are too short.
+ return (state[length - 1] == calcChecksum(state, length));
+}
+
+uint8_t *IRHitachiAc1::getRaw(void) {
+ checksum();
+ return remote_state;
+}
+
+void IRHitachiAc1::setRaw(const uint8_t new_code[], const uint16_t length) {
+ memcpy(remote_state, new_code, std::min(length, kHitachiAc1StateLength));
+}
+
+#if SEND_HITACHI_AC
+void IRHitachiAc1::send(const uint16_t repeat) {
+ _irsend.sendHitachiAC1(getRaw(), kHitachiAc1StateLength, repeat);
+ // Clear the toggle bits as we have actioned them by sending them.
+ setPowerToggle(false);
+ setSwingToggle(false);
+}
+#endif // SEND_HITACHI_AC
+
+hitachi_ac1_remote_model_t IRHitachiAc1::getModel(void) {
+ switch (GETBITS8(remote_state[kHitachiAc1ModelByte], kHitachiAc1ModelOffset,
+ kHitachiAc1ModelSize)) {
+ case kHitachiAc1Model_B: return hitachi_ac1_remote_model_t::R_LT0541_HTA_B;
+ default: return hitachi_ac1_remote_model_t::R_LT0541_HTA_A;
+ }
+}
+
+void IRHitachiAc1::setModel(const hitachi_ac1_remote_model_t model) {
+ uint8_t value = 0;
+ switch (model) {
+ case hitachi_ac1_remote_model_t::R_LT0541_HTA_B:
+ value = kHitachiAc1Model_B;
+ break;
+ default:
+ value = kHitachiAc1Model_A; // i.e. 'A' mode.
+ }
+ setBits(&remote_state[kHitachiAc1ModelByte], kHitachiAc1ModelOffset,
+ kHitachiAc1ModelSize, value);
+}
+
+bool IRHitachiAc1::getPower(void) {
+ return GETBIT8(remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerOffset);
+}
+
+void IRHitachiAc1::setPower(const bool on) {
+ // If the power changes, set the power toggle bit.
+ if (on != getPower()) setPowerToggle(true);
+ setBit(&remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerOffset, on);
+}
+
+bool IRHitachiAc1::getPowerToggle(void) {
+ return GETBIT8(remote_state[kHitachiAc1PowerByte],
+ kHitachiAc1PowerToggleOffset);
+}
+
+void IRHitachiAc1::setPowerToggle(const bool on) {
+ setBit(&remote_state[kHitachiAc1PowerByte], kHitachiAc1PowerToggleOffset, on);
+}
+
+void IRHitachiAc1::on(void) { setPower(true); }
+
+void IRHitachiAc1::off(void) { setPower(false); }
+
+uint8_t IRHitachiAc1::getMode(void) {
+ return GETBITS8(remote_state[kHitachiAc1ModeByte], kHitachiAc1ModeOffset,
+ kHitachiAc1ModeSize);
+}
+
+void IRHitachiAc1::setMode(const uint8_t mode) {
+ switch (mode) {
+ case kHitachiAc1Auto:
+ setTemp(kHitachiAc1TempAuto);
+ // FALL THRU
+ case kHitachiAc1Fan:
+ case kHitachiAc1Heat:
+ case kHitachiAc1Cool:
+ case kHitachiAc1Dry:
+ setBits(&remote_state[kHitachiAc1ModeByte], kHitachiAc1ModeOffset,
+ kHitachiAc1ModeSize, mode);
+ setSleep(getSleep()); // Correct the sleep mode if required.
+ setFan(getFan()); // Correct the fan speed if required.
+ break;
+ default: setMode(kHitachiAc1Auto);
+ }
+ switch (mode) {
+ case kHitachiAc1Fan:
+ case kHitachiAc1Heat:
+ // Auto fan speed not available in these modes, change if needed.
+ if (getFan() == kHitachiAc1FanAuto) setFan(kHitachiAc1FanLow);
+ }
+}
+
+uint8_t IRHitachiAc1::getTemp(void) {
+ return reverseBits(GETBITS8(remote_state[kHitachiAc1TempByte],
+ kHitachiAc1TempOffset, kHitachiAc1TempSize),
+ kHitachiAc1TempSize) + kHitachiAc1TempDelta;
+}
+
+void IRHitachiAc1::setTemp(const uint8_t celsius) {
+ if (getMode() == kHitachiAc1Auto) return; // Can't change temp in Auto mode.
+ uint8_t temp = std::min(celsius, kHitachiAcMaxTemp);
+ temp = std::max(temp, kHitachiAcMinTemp);
+ temp -= kHitachiAc1TempDelta;
+ temp = reverseBits(temp, kHitachiAc1TempSize);
+ setBits(&remote_state[kHitachiAc1TempByte], kHitachiAc1TempOffset,
+ kHitachiAc1TempSize, temp);
+}
+
+uint8_t IRHitachiAc1::getFan(void) {
+ return GETBITS8(remote_state[kHitachiAc1FanByte], kHitachiAc1FanOffset,
+ kHitachiAc1FanSize);
+}
+
+void IRHitachiAc1::setFan(const uint8_t speed, const bool force) {
+ if (!force) {
+ switch (getMode()) {
+ case kHitachiAc1Dry:
+ setFan(kHitachiAc1FanLow, true); // Dry is locked to Low speed.
+ return;
+ case kHitachiAc1Auto:
+ setFan(kHitachiAc1FanAuto, true); // Auto is locked to Auto speed.
+ return;
+ }
+ }
+ switch (speed) {
+ case kHitachiAc1FanAuto:
+ switch (getMode()) {
+ case kHitachiAc1Heat:
+ case kHitachiAc1Fan: return; // Auto speed not allowed in these modes.
+ }
+ // FALL THRU
+ case kHitachiAc1FanHigh:
+ case kHitachiAc1FanMed:
+ case kHitachiAc1FanLow:
+ setBits(&remote_state[kHitachiAc1FanByte], kHitachiAc1FanOffset,
+ kHitachiAc1FanSize, speed);
+ break;
+ default: setFan(kHitachiAc1FanAuto);
+ }
+}
+
+bool IRHitachiAc1::getSwingToggle(void) {
+ return GETBIT8(remote_state[kHitachiAc1SwingByte],
+ kHitachiAc1SwingToggleOffset);
+}
+
+void IRHitachiAc1::setSwingToggle(const bool toggle) {
+ setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingToggleOffset,
+ toggle);
+}
+
+bool IRHitachiAc1::getSwingV(void) {
+ return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingVOffset);
+}
+
+void IRHitachiAc1::setSwingV(const bool on) {
+ setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingVOffset, on);
+}
+
+bool IRHitachiAc1::getSwingH(void) {
+ return GETBIT8(remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingHOffset);
+}
+
+void IRHitachiAc1::setSwingH(const bool on) {
+ setBit(&remote_state[kHitachiAc1SwingByte], kHitachiAc1SwingHOffset, on);
+}
+
+uint8_t IRHitachiAc1::getSleep(void) {
+ return GETBITS8(remote_state[kHitachiAc1SleepByte], kHitachiAc1SleepOffset,
+ kHitachiAc1SleepSize);
+}
+
+void IRHitachiAc1::setSleep(const uint8_t mode) {
+ // Sleep modes only available in Auto & Cool modes, otherwise it's off.
+ switch (getMode()) {
+ case kHitachiAc1Auto:
+ case kHitachiAc1Cool:
+ setBits(&remote_state[kHitachiAc1SleepByte], kHitachiAc1SleepOffset,
+ kHitachiAc1SleepSize, std::min(mode, kHitachiAc1Sleep4));
+ break;
+ default:
+ setBits(&remote_state[kHitachiAc1SleepByte], kHitachiAc1SleepOffset,
+ kHitachiAc1SleepSize, kHitachiAc1SleepOff);
+ }
+}
+
+void IRHitachiAc1::setOnTimer(const uint16_t mins) {
+ const uint16_t mins_lsb = reverseBits(mins, kHitachiAc1TimerSize);
+ remote_state[kHitachiAc1OnTimerLowByte] = GETBITS16(mins_lsb, 8, 8);
+ remote_state[kHitachiAc1OnTimerHighByte] = GETBITS16(mins_lsb, 0, 8);
+}
+
+uint16_t IRHitachiAc1::getOnTimer(void) {
+ return reverseBits(
+ (remote_state[kHitachiAc1OnTimerLowByte] << 8) |
+ remote_state[kHitachiAc1OnTimerHighByte], kHitachiAc1TimerSize);
+}
+
+void IRHitachiAc1::setOffTimer(const uint16_t mins) {
+ const uint16_t mins_lsb = reverseBits(mins, kHitachiAc1TimerSize);
+ remote_state[kHitachiAc1OffTimerLowByte] = GETBITS16(mins_lsb, 8, 8);
+ remote_state[kHitachiAc1OffTimerHighByte] = GETBITS16(mins_lsb, 0, 8);
+}
+
+uint16_t IRHitachiAc1::getOffTimer(void) {
+ return reverseBits(
+ (remote_state[kHitachiAc1OffTimerLowByte] << 8) |
+ remote_state[kHitachiAc1OffTimerHighByte], kHitachiAc1TimerSize);
+}
+
+// Convert a standard A/C mode into its native mode.
+uint8_t IRHitachiAc1::convertMode(const stdAc::opmode_t mode) {
+ switch (mode) {
+ case stdAc::opmode_t::kCool: return kHitachiAc1Cool;
+ case stdAc::opmode_t::kHeat: return kHitachiAc1Heat;
+ case stdAc::opmode_t::kDry: return kHitachiAc1Dry;
+ case stdAc::opmode_t::kFan: return kHitachiAc1Fan;
+ default: return kHitachiAc1Auto;
+ }
+}
+
+// Convert a standard A/C Fan speed into its native fan speed.
+uint8_t IRHitachiAc1::convertFan(const stdAc::fanspeed_t speed) {
+ switch (speed) {
+ case stdAc::fanspeed_t::kMin:
+ case stdAc::fanspeed_t::kLow: return kHitachiAc1FanLow;
+ case stdAc::fanspeed_t::kMedium: return kHitachiAc1FanMed;
+ case stdAc::fanspeed_t::kHigh:
+ case stdAc::fanspeed_t::kMax: return kHitachiAc1FanHigh;
+ default: return kHitachiAc1FanAuto;
+ }
+}
+
+// Convert a native mode to it's common equivalent.
+stdAc::opmode_t IRHitachiAc1::toCommonMode(const uint8_t mode) {
+ switch (mode) {
+ case kHitachiAc1Cool: return stdAc::opmode_t::kCool;
+ case kHitachiAc1Heat: return stdAc::opmode_t::kHeat;
+ case kHitachiAc1Dry: return stdAc::opmode_t::kDry;
+ case kHitachiAc1Fan: return stdAc::opmode_t::kFan;
+ default: return stdAc::opmode_t::kAuto;
+ }
+}
+
+// Convert a native fan speed to it's common equivalent.
+stdAc::fanspeed_t IRHitachiAc1::toCommonFanSpeed(const uint8_t speed) {
+ switch (speed) {
+ case kHitachiAc1FanHigh: return stdAc::fanspeed_t::kMax;
+ case kHitachiAc1FanMed: return stdAc::fanspeed_t::kMedium;
+ case kHitachiAc1FanLow: return stdAc::fanspeed_t::kLow;
+ default: return stdAc::fanspeed_t::kAuto;
+ }
+}
+
+// Convert the A/C state to it's common equivalent.
+stdAc::state_t IRHitachiAc1::toCommon(void) {
+ stdAc::state_t result;
+ result.protocol = decode_type_t::HITACHI_AC1;
+ result.model = this->getModel();
+ result.power = this->getPower();
+ result.mode = this->toCommonMode(this->getMode());
+ result.celsius = true;
+ result.degrees = this->getTemp();
+ result.fanspeed = this->toCommonFanSpeed(this->getFan());
+ result.swingv = this->getSwingV() ? stdAc::swingv_t::kAuto :
+ stdAc::swingv_t::kOff;
+ result.swingh = this->getSwingH() ? stdAc::swingh_t::kAuto :
+ stdAc::swingh_t::kOff;
+ result.sleep = this->getSleep() ? 0 : -1;
+ // Not supported.
+ result.quiet = false;
+ result.turbo = false;
+ result.clean = false;
+ result.econo = false;
+ result.filter = false;
+ result.light = false;
+ result.beep = false;
+ result.clock = -1;
+ return result;
+}
+
+// Convert the internal state into a human readable string.
+String IRHitachiAc1::toString(void) {
+ String result = "";
+ result.reserve(170); // Reserve some heap for the string to reduce fragging.
+ result += addModelToString(decode_type_t::HITACHI_AC1, getModel(), false);
+ result += addBoolToString(getPower(), kPowerStr);
+ result += addBoolToString(getPowerToggle(), kPowerToggleStr);
+ result += addModeToString(getMode(), kHitachiAc1Auto, kHitachiAc1Cool,
+ kHitachiAc1Heat, kHitachiAc1Dry, kHitachiAc1Fan);
+ result += addTempToString(getTemp());
+ result += addFanToString(getFan(), kHitachiAc1FanHigh, kHitachiAc1FanLow,
+ kHitachiAc1FanAuto, kHitachiAc1FanAuto,
+ kHitachiAc1FanMed);
+ result += addBoolToString(getSwingToggle(), kSwingVToggleStr);
+ result += addBoolToString(getSwingV(), kSwingVStr);
+ result += addBoolToString(getSwingH(), kSwingHStr);
+ result += addLabeledString(getSleep() ? uint64ToString(getSleep()) : kOffStr,
+ kSleepStr);
+ result += addLabeledString(getOnTimer() ? minsToString(getOnTimer())
+ : kOffStr,
+ kOnTimerStr);
+ result += addLabeledString(getOffTimer() ? minsToString(getOffTimer())
+ : kOffStr,
+ kOffTimerStr);
+ return result;
+}
+
#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2)
// Decode the supplied Hitachi A/C message.
//
@@ -367,7 +729,7 @@ String IRHitachiAc::toString(void) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Probably works.
+// Status: STABLE / Expected to work.
//
// Supported devices:
// Hitachi A/C Series VI (Circa 2007) / Remote: LT0541-HTA
@@ -412,6 +774,9 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset,
if (nbits / 8 == kHitachiAcStateLength &&
!IRHitachiAc::validChecksum(results->state, kHitachiAcStateLength))
return false;
+ if (nbits / 8 == kHitachiAc1StateLength &&
+ !IRHitachiAc1::validChecksum(results->state, kHitachiAc1StateLength))
+ return false;
}
// Success
@@ -800,3 +1165,142 @@ String IRHitachiAc424::toString(void) {
result += ')';
return result;
}
+
+
+#if SEND_HITACHI_AC3
+// Send HITACHI_AC3 messages
+//
+// Note: This protocol is almost exactly the same as HitachiAC424 except this
+// variant has subtle timing differences.
+// There are five(5) typical sizes:
+// * kHitachiAc3MinStateLength (Cancel Timer)
+// * kHitachiAc3MinStateLength + 2 (Change Temp)
+// * kHitachiAc3StateLength - 6 (Change Mode)
+// * kHitachiAc3StateLength- 4 (Normal)
+// * kHitachiAc3StateLength (Set Timer)
+//
+// Args:
+// data: An array of bytes containing the IR command.
+// It is assumed to be in LSBF order for this code.
+// nbytes: Nr. of bytes of data in the array.
+// repeat: Nr. of times the message is to be repeated.
+//
+// Status: STABLE / Working fine.
+void IRsend::sendHitachiAc3(const uint8_t data[], const uint16_t nbytes,
+ const uint16_t repeat) {
+ // Header + Data + Footer
+ sendGeneric(kHitachiAc3HdrMark, kHitachiAc3HdrSpace,
+ kHitachiAc3BitMark, kHitachiAc3OneSpace,
+ kHitachiAc3BitMark, kHitachiAc3ZeroSpace,
+ kHitachiAc3BitMark, kHitachiAcMinGap,
+ data, nbytes, // Bytes
+ kHitachiAcFreq, false, repeat, kDutyDefault);
+}
+#endif // SEND_HITACHI_AC3
+
+
+// Class for handling the remote control on a Hitachi_AC3 53 A/C message
+IRHitachiAc3::IRHitachiAc3(const uint16_t pin, const bool inverted,
+ const bool use_modulation)
+ : _irsend(pin, inverted, use_modulation) { stateReset(); }
+
+// Reset to auto fan, cooling, 23° Celcius
+void IRHitachiAc3::stateReset(void) {
+ for (uint8_t i = 0; i < kHitachiAc3StateLength; i++)
+ remote_state[i] = 0x00;
+ remote_state[0] = 0x01;
+ remote_state[1] = 0x10;
+ remote_state[3] = 0x40;
+ remote_state[5] = 0xFF;
+ remote_state[7] = 0xE8;
+ remote_state[9] = 0x89;
+ remote_state[11] = 0x0B;
+ remote_state[13] = 0x3F;
+ remote_state[15] = 0x15;
+ remote_state[21] = 0x4B;
+ remote_state[23] = 0x18;
+ setInvertedStates();
+}
+
+void IRHitachiAc3::setInvertedStates(const uint16_t length) {
+ for (uint8_t i = 3; i < length - 1; i += 2)
+ remote_state[i + 1] = ~remote_state[i];
+}
+
+bool IRHitachiAc3::hasInvertedStates(const uint8_t state[],
+ const uint16_t length) {
+ for (uint8_t i = 3; i < length - 1; i += 2)
+ if ((state[i + 1] ^ state[i]) != 0xFF) return false;
+ return true;
+}
+
+void IRHitachiAc3::begin(void) { _irsend.begin(); }
+
+uint8_t *IRHitachiAc3::getRaw(void) {
+ setInvertedStates();
+ return remote_state;
+}
+
+void IRHitachiAc3::setRaw(const uint8_t new_code[], const uint16_t length) {
+ memcpy(remote_state, new_code, std::min(length, kHitachiAc3StateLength));
+}
+
+#if DECODE_HITACHI_AC3
+// Decode the supplied HitachiAc3 A/C message.
+//
+// Note: This protocol is almost exactly the same as HitachiAC424 except this
+// variant has subtle timing differences and multiple lengths.
+//
+// Args:
+// results: Ptr to the data to decode and where to store the decode result.
+// offset: The starting index to use when attempting to decode the raw data.
+// Typically/Defaults to kStartOffset.
+// nbits: The number of data bits to expect. Typically kHitachiAc3Bits.
+// strict: Flag indicating if we should perform strict matching.
+// Returns:
+// boolean: True if it can decode it, false if it can't.
+//
+// Status: STABLE / Works fine.
+//
+// Supported devices:
+// Hitachi PC-LH3B
+//
+// Ref:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1060
+bool IRrecv::decodeHitachiAc3(decode_results *results, uint16_t offset,
+ const uint16_t nbits,
+ const bool strict) {
+ if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset)
+ return false; // Too short a message to match.
+ if (strict) {
+ // Check the requested bit length.
+ switch (nbits) {
+ case kHitachiAc3MinBits: // Cancel Timer (Min Size)
+ case kHitachiAc3MinBits + 2 * 8: // Change Temp
+ case kHitachiAc3Bits - 6 * 8: // Change Mode
+ case kHitachiAc3Bits - 4 * 8: // Normal
+ case kHitachiAc3Bits: // Set Temp (Max Size)
+ break;
+ default: return false;
+ }
+ }
+
+ // Header + Data + Footer
+ if (!matchGeneric(results->rawbuf + offset, results->state,
+ results->rawlen - offset, nbits,
+ kHitachiAc3HdrMark, kHitachiAc3HdrSpace,
+ kHitachiAc3BitMark, kHitachiAc3OneSpace,
+ kHitachiAc3BitMark, kHitachiAc3ZeroSpace,
+ kHitachiAc3BitMark, kHitachiAcMinGap, true,
+ kUseDefTol, 0, false))
+ return false; // We failed to find any data.
+
+ // Compliance
+ if (strict && !IRHitachiAc3::hasInvertedStates(results->state, nbits / 8))
+ return false;
+ // Success
+ results->decode_type = decode_type_t::HITACHI_AC3;
+ results->bits = nbits;
+ return true;
+}
+#endif // DECODE_HITACHI_AC3
diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.h b/lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.h
new file mode 100644
index 000000000..0db3552ff
--- /dev/null
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Hitachi.h
@@ -0,0 +1,330 @@
+// Hitachi A/C
+//
+// Copyright 2018-2020 David Conran
+
+// Supports:
+// Brand: Hitachi, Model: RAS-35THA6 remote
+// Brand: Hitachi, Model: LT0541-HTA remote
+// Brand: Hitachi, Model: Series VI A/C (Circa 2007)
+// Brand: Hitachi, Model: RAR-8P2 remote
+// Brand: Hitachi, Model: RAS-AJ25H A/C
+// Brand: Hitachi, Model: PC-LH3B (HITACHI_AC3)
+// Brand: Hitachi, Model: KAZE-312KSDP A/C (HITACHI_AC1)
+// Brand: Hitachi, Model: R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
+
+#ifndef IR_HITACHI_H_
+#define IR_HITACHI_H_
+
+#define __STDC_LIMIT_MACROS
+#include
+#ifndef UNIT_TEST
+#include
+#endif
+#include "IRremoteESP8266.h"
+#include "IRsend.h"
+#ifdef UNIT_TEST
+#include "IRsend_test.h"
+#endif
+
+// Constants
+const uint16_t kHitachiAcFreq = 38000; // Hz.
+const uint8_t kHitachiAcAuto = 2;
+const uint8_t kHitachiAcHeat = 3;
+const uint8_t kHitachiAcCool = 4;
+const uint8_t kHitachiAcDry = 5;
+const uint8_t kHitachiAcFan = 0xC;
+const uint8_t kHitachiAcFanAuto = 1;
+const uint8_t kHitachiAcFanLow = 2;
+const uint8_t kHitachiAcFanMed = 3;
+const uint8_t kHitachiAcFanHigh = 5;
+const uint8_t kHitachiAcMinTemp = 16; // 16C
+const uint8_t kHitachiAcMaxTemp = 32; // 32C
+const uint8_t kHitachiAcAutoTemp = 23; // 23C
+const uint8_t kHitachiAcPowerOffset = 0;
+const uint8_t kHitachiAcSwingOffset = 7;
+
+// HitachiAc424
+// Byte[11]
+const uint8_t kHitachiAc424ButtonByte = 11;
+const uint8_t kHitachiAc424ButtonPowerMode = 0x13;
+const uint8_t kHitachiAc424ButtonFan = 0x42;
+const uint8_t kHitachiAc424ButtonTempDown = 0x43;
+const uint8_t kHitachiAc424ButtonTempUp = 0x44;
+const uint8_t kHitachiAc424ButtonSwingV = 0x81;
+
+// Byte[13]
+const uint8_t kHitachiAc424TempByte = 13;
+const uint8_t kHitachiAc424TempOffset = 2;
+const uint8_t kHitachiAc424TempSize = 6;
+const uint8_t kHitachiAc424MinTemp = 16; // 16C
+const uint8_t kHitachiAc424MaxTemp = 32; // 32C
+const uint8_t kHitachiAc424FanTemp = 27; // 27C
+
+// Byte[25]
+const uint8_t kHitachiAc424ModeByte = 25;
+const uint8_t kHitachiAc424Fan = 1;
+const uint8_t kHitachiAc424Cool = 3;
+const uint8_t kHitachiAc424Dry = 5;
+const uint8_t kHitachiAc424Heat = 6;
+const uint8_t kHitachiAc424FanByte = kHitachiAc424ModeByte;
+const uint8_t kHitachiAc424FanMin = 1;
+const uint8_t kHitachiAc424FanLow = 2;
+const uint8_t kHitachiAc424FanMedium = 3;
+const uint8_t kHitachiAc424FanHigh = 4;
+const uint8_t kHitachiAc424FanAuto = 5;
+const uint8_t kHitachiAc424FanMax = 6;
+const uint8_t kHitachiAc424FanMaxDry = 2;
+// Byte[27]
+const uint8_t kHitachiAc424PowerByte = 27;
+const uint8_t kHitachiAc424PowerOn = 0xF1;
+const uint8_t kHitachiAc424PowerOff = 0xE1;
+
+// HitachiAc1
+// Byte[3] (Model)
+const uint8_t kHitachiAc1ModelByte = 3;
+const uint8_t kHitachiAc1ModelOffset = 6; // Mask 0b11000000
+const uint8_t kHitachiAc1Model_A = 0b10;
+const uint8_t kHitachiAc1Model_B = 0b01;
+const uint8_t kHitachiAc1ModelSize = 2;
+
+// Byte[5] (Mode & Fan)
+const uint8_t kHitachiAc1ModeByte = 5;
+const uint8_t kHitachiAc1ModeOffset = 4;
+const uint8_t kHitachiAc1ModeSize = 4; // Mask 0b11110000
+const uint8_t kHitachiAc1Dry = 0b0010; // 2
+const uint8_t kHitachiAc1Fan = 0b0100; // 4
+const uint8_t kHitachiAc1Cool = 0b0110; // 6
+const uint8_t kHitachiAc1Heat = 0b1001; // 9
+const uint8_t kHitachiAc1Auto = 0b1110; // 14
+const uint8_t kHitachiAc1FanByte = kHitachiAc1ModeByte;
+const uint8_t kHitachiAc1FanOffset = 0;
+const uint8_t kHitachiAc1FanSize = 4; // Mask 0b0001111
+const uint8_t kHitachiAc1FanAuto = 1; // 0b0001
+const uint8_t kHitachiAc1FanHigh = 2; // 0b0010
+const uint8_t kHitachiAc1FanMed = 4; // 0b0100
+const uint8_t kHitachiAc1FanLow = 8; // 0b1000
+// Byte[6] (Temperature)
+// Note: Temp is stored in LSB order.
+const uint8_t kHitachiAc1TempByte = 6;
+const uint8_t kHitachiAc1TempOffset = 2;
+const uint8_t kHitachiAc1TempSize = 5; // Mask 0b01111100
+const uint8_t kHitachiAc1TempDelta = 7;
+const uint8_t kHitachiAc1TempAuto = 25; // Celsius
+// Note: Timers are nr. of minutes & stored in LSB order.
+// Byte[7-8] (Off Timer)
+const uint8_t kHitachiAc1TimerSize = 16; // Mask 0b1111111111111111
+const uint8_t kHitachiAc1OffTimerLowByte = 7;
+const uint8_t kHitachiAc1OffTimerHighByte = 8;
+// Byte[9-10] (On Timer)
+const uint8_t kHitachiAc1OnTimerLowByte = 9;
+const uint8_t kHitachiAc1OnTimerHighByte = 10;
+// Byte[11] (Power/Swing/Sleep)
+const uint8_t kHitachiAc1PowerByte = 11;
+const uint8_t kHitachiAc1PowerOffset = 5; // Mask 0b00100000
+const uint8_t kHitachiAc1PowerToggleOffset = 4; // Mask 0b00010000
+const uint8_t kHitachiAc1SwingByte = kHitachiAc1PowerByte;
+const uint8_t kHitachiAc1SwingHOffset = 7; // Mask 0b10000000
+const uint8_t kHitachiAc1SwingVOffset = 6; // Mask 0b01000000
+const uint8_t kHitachiAc1SwingToggleOffset = 0; // Mask 0b00000001
+const uint8_t kHitachiAc1SleepByte = kHitachiAc1PowerByte;
+const uint8_t kHitachiAc1SleepOffset = 1; // Mask 0b00001110
+const uint8_t kHitachiAc1SleepSize = 3; // Mask 0b00001110
+const uint8_t kHitachiAc1SleepOff = 0b000;
+const uint8_t kHitachiAc1Sleep1 = 0b001;
+const uint8_t kHitachiAc1Sleep2 = 0b010;
+const uint8_t kHitachiAc1Sleep3 = 0b011;
+const uint8_t kHitachiAc1Sleep4 = 0b100;
+// Byte[12] (Checksum)
+const uint8_t kHitachiAc1ChecksumStartByte = 5;
+
+
+// Classes
+class IRHitachiAc {
+ public:
+ explicit IRHitachiAc(const uint16_t pin, const bool inverted = false,
+ const bool use_modulation = true);
+
+ void stateReset(void);
+#if SEND_HITACHI_AC
+ void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+ uint8_t calibrate(void) { return _irsend.calibrate(); }
+#endif // SEND_HITACHI_AC
+ 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 speed);
+ uint8_t getFan(void);
+ void setMode(const uint8_t mode);
+ uint8_t getMode(void);
+ void setSwingVertical(const bool on);
+ bool getSwingVertical(void);
+ void setSwingHorizontal(const bool on);
+ bool getSwingHorizontal(void);
+ uint8_t* getRaw(void);
+ void setRaw(const uint8_t new_code[],
+ const uint16_t length = kHitachiAcStateLength);
+ static bool validChecksum(const uint8_t state[],
+ const uint16_t length = kHitachiAcStateLength);
+ static uint8_t calcChecksum(const uint8_t state[],
+ const uint16_t length = kHitachiAcStateLength);
+ uint8_t convertMode(const stdAc::opmode_t mode);
+ uint8_t convertFan(const stdAc::fanspeed_t speed);
+ static stdAc::opmode_t toCommonMode(const uint8_t mode);
+ static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ stdAc::state_t toCommon(void);
+ String toString(void);
+#ifndef UNIT_TEST
+
+ private:
+ IRsend _irsend;
+#else
+ IRsendTest _irsend;
+#endif
+ // The state of the IR remote in IR code form.
+ uint8_t remote_state[kHitachiAcStateLength];
+ void checksum(const uint16_t length = kHitachiAcStateLength);
+ uint8_t _previoustemp;
+};
+
+class IRHitachiAc1 {
+ public:
+ explicit IRHitachiAc1(const uint16_t pin, const bool inverted = false,
+ const bool use_modulation = true);
+
+ void stateReset(void);
+#if SEND_HITACHI_AC1
+ void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+ uint8_t calibrate(void) { return _irsend.calibrate(); }
+#endif // SEND_HITACHI_AC1
+ void begin(void);
+ void on(void);
+ void off(void);
+ void setModel(const hitachi_ac1_remote_model_t model);
+ hitachi_ac1_remote_model_t getModel(void);
+ void setPower(const bool on);
+ bool getPower(void);
+ void setPowerToggle(const bool on);
+ bool getPowerToggle(void);
+ void setTemp(const uint8_t temp);
+ uint8_t getTemp(void);
+ void setFan(const uint8_t speed, const bool force = false);
+ uint8_t getFan(void);
+ void setMode(const uint8_t mode);
+ uint8_t getMode(void);
+ void setSwingToggle(const bool toggle);
+ bool getSwingToggle(void);
+ void setSwingV(const bool on);
+ bool getSwingV(void);
+ void setSwingH(const bool on);
+ bool getSwingH(void);
+ void setSleep(const uint8_t mode);
+ uint8_t getSleep(void);
+ void setOnTimer(const uint16_t mins);
+ uint16_t getOnTimer(void);
+ void setOffTimer(const uint16_t mins);
+ uint16_t getOffTimer(void);
+ uint8_t* getRaw(void);
+ void setRaw(const uint8_t new_code[],
+ const uint16_t length = kHitachiAc1StateLength);
+ static bool validChecksum(const uint8_t state[],
+ const uint16_t length = kHitachiAc1StateLength);
+ static uint8_t calcChecksum(const uint8_t state[],
+ const uint16_t length = kHitachiAc1StateLength);
+ uint8_t convertMode(const stdAc::opmode_t mode);
+ uint8_t convertFan(const stdAc::fanspeed_t speed);
+ static stdAc::opmode_t toCommonMode(const uint8_t mode);
+ static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ stdAc::state_t toCommon(void);
+ String toString(void);
+#ifndef UNIT_TEST
+
+ private:
+ IRsend _irsend;
+#else
+ IRsendTest _irsend;
+#endif
+ // The state of the IR remote in IR code form.
+ uint8_t remote_state[kHitachiAc1StateLength];
+ void checksum(const uint16_t length = kHitachiAc1StateLength);
+};
+
+class IRHitachiAc424 {
+ public:
+ explicit IRHitachiAc424(const uint16_t pin, const bool inverted = false,
+ const bool use_modulation = true);
+
+ void stateReset(void);
+#if SEND_HITACHI_AC424
+ void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+ uint8_t calibrate(void) { return _irsend.calibrate(); }
+#endif // SEND_HITACHI_AC424
+ void begin(void);
+ void on(void);
+ void off(void);
+ void setPower(const bool on);
+ bool getPower(void);
+ void setTemp(const uint8_t temp, bool setPrevious = true);
+ uint8_t getTemp(void);
+ void setFan(const uint8_t speed);
+ uint8_t getFan(void);
+ uint8_t getButton(void);
+ void setButton(const uint8_t button);
+ void setSwingVToggle(const bool on);
+ bool getSwingVToggle(void);
+ void setMode(const uint8_t mode);
+ uint8_t getMode(void);
+ uint8_t* getRaw(void);
+ void setRaw(const uint8_t new_code[],
+ const uint16_t length = kHitachiAc424StateLength);
+ uint8_t convertMode(const stdAc::opmode_t mode);
+ uint8_t convertFan(const stdAc::fanspeed_t speed);
+ static stdAc::opmode_t toCommonMode(const uint8_t mode);
+ static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ stdAc::state_t toCommon(void);
+ String toString(void);
+#ifndef UNIT_TEST
+
+ private:
+ IRsend _irsend;
+#else
+ IRsendTest _irsend;
+#endif
+ // The state of the IR remote in IR code form.
+ uint8_t remote_state[kHitachiAc424StateLength];
+ void setInvertedStates(void);
+ uint8_t _previoustemp;
+};
+
+class IRHitachiAc3 {
+ public:
+ explicit IRHitachiAc3(const uint16_t pin, const bool inverted = false,
+ const bool use_modulation = true);
+
+ void stateReset(void);
+#if SEND_HITACHI_AC3
+ void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
+ uint8_t calibrate(void) { return _irsend.calibrate(); }
+#endif // SEND_HITACHI_AC3
+ void begin(void);
+ uint8_t getMode(void);
+ uint8_t* getRaw(void);
+ void setRaw(const uint8_t new_code[],
+ const uint16_t length = kHitachiAc3StateLength);
+ static bool hasInvertedStates(const uint8_t state[], const uint16_t length);
+#ifndef UNIT_TEST
+
+ private:
+ IRsend _irsend;
+#else
+ IRsendTest _irsend;
+#endif
+ // The state of the IR remote in IR code form.
+ uint8_t remote_state[kHitachiAc3StateLength];
+ void setInvertedStates(const uint16_t length = kHitachiAc3StateLength);
+};
+
+#endif // IR_HITACHI_H_
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Inax.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Inax.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Inax.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Inax.cpp
index 9822e750b..b57742a12 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Inax.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Inax.cpp
@@ -31,7 +31,7 @@ const uint16_t kInaxMinGap = 40000;
// nbits: The bit size of the message being sent. typically kInaxBits.
// repeat: The number of times the message is to be repeated.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Working.
//
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/706
void IRsend::sendInax(const uint64_t data, const uint16_t nbits,
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_JVC.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_JVC.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_JVC.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_JVC.cpp
index 128efdf08..7e1e5de27 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_JVC.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_JVC.cpp
@@ -78,7 +78,7 @@ void IRsend::sendJVC(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// A raw JVC message.
//
-// Status: BETA / Should work fine.
+// Status: STABLE / Works fine.
//
// Ref:
// http://www.sbprojects.com/knowledge/ir/jvc.php
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Kelvinator.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Kelvinator.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Kelvinator.h b/lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Kelvinator.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Kelvinator.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_LG.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_LG.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_LG.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_LG.cpp
index b30dba082..1024548ca 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_LG.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_LG.cpp
@@ -157,7 +157,7 @@ void IRsend::sendLG2(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// A raw 28-bit LG message code suitable for sendLG() etc.
//
-// Status: BETA / Should work.
+// Status: STABLE / Works.
//
// Notes:
// e.g. Sequence of bits = address + command + checksum.
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_LG.h b/lib/IRremoteESP8266-2.7.5/src/ir_LG.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_LG.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_LG.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Lasertag.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Lasertag.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Lasertag.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Lasertag.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Lego.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Lego.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Lego.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Lego.cpp
index 502352218..b2d2f2d0e 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Lego.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Lego.cpp
@@ -74,7 +74,7 @@ void IRsend::sendLegoPf(const uint64_t data, const uint16_t nbits,
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Appears to work.
+// Status: STABLE / Appears to work.
bool IRrecv::decodeLegoPf(decode_results* results, uint16_t offset,
const uint16_t nbits, const bool strict) {
// Check if can possibly be a valid LEGO message.
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Lutron.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Lutron.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Lutron.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Lutron.cpp
index 094932e5d..8ea4f0b3a 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Lutron.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Lutron.cpp
@@ -65,7 +65,7 @@ void IRsend::sendLutron(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: ALPHA / Untested.
+// Status: STABLE / Working.
//
// Notes:
//
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_MWM.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_MWM.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_MWM.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_MWM.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Magiquest.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Magiquest.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Magiquest.h b/lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Magiquest.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Magiquest.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Midea.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Midea.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Midea.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Midea.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Midea.h b/lib/IRremoteESP8266-2.7.5/src/ir_Midea.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Midea.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Midea.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Mitsubishi.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Mitsubishi.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.cpp
index 68098f40a..b8d62e109 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Mitsubishi.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.cpp
@@ -107,7 +107,7 @@ using irutils::setBits;
// nbits: Nr. of bits of data to be sent. Typically kMitsubishiBits.
// repeat: Nr. of additional times the message is to be sent.
//
-// Status: ALPHA / untested.
+// Status: STABLE / Working.
//
// Notes:
// This protocol appears to have no header.
@@ -134,7 +134,7 @@ void IRsend::sendMitsubishi(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / previously working.
+// Status: STABLE / Working.
//
// Notes:
// This protocol appears to have no header.
@@ -174,7 +174,7 @@ bool IRrecv::decodeMitsubishi(decode_results *results, uint16_t offset,
// nbits: Nr. of bits of data to be sent. Typically kMitsubishiBits.
// repeat: Nr. of additional times the message is to be sent.
//
-// Status: ALPHA / untested.
+// Status: BETA / Probably works.
//
// Notes:
// Based on a Mitsubishi HC3000 projector's remote.
@@ -214,7 +214,7 @@ void IRsend::sendMitsubishi2(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Works with simulated data.
+// Status: STABLE / Works.
//
// Notes:
// Hardware supported:
@@ -270,7 +270,7 @@ bool IRrecv::decodeMitsubishi2(decode_results *results, uint16_t offset,
// repeat: Nr. of times the message is to be repeated.
// (Default = kMitsubishiACMinRepeat).
//
-// Status: BETA / Appears to be working.
+// Status: STABLE / Working.
//
void IRsend::sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) {
@@ -296,7 +296,7 @@ void IRsend::sendMitsubishiAC(const unsigned char data[], const uint16_t nbytes,
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: ALPHA / Under development
+// Status: BETA / Probably works
//
// Ref:
// https://www.analysir.com/blog/2015/01/06/reverse-engineering-mitsubishi-ac-infrared-protocol/
@@ -804,7 +804,7 @@ String IRMitsubishiAC::toString(void) {
// repeat: Nr. of times the message is to be repeated.
// (Default = kMitsubishi136MinRepeat).
//
-// Status: ALPHA / Probably working. Needs to be tested against a real device.
+// Status: BETA / Probably working. Needs to be tested against a real device.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/888
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Mitsubishi.h b/lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Mitsubishi.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Mitsubishi.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_MitsubishiHeavy.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_MitsubishiHeavy.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_MitsubishiHeavy.h b/lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_MitsubishiHeavy.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_MitsubishiHeavy.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_NEC.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_NEC.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_NEC.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_NEC.cpp
index 2f870f58c..9145f5c24 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_NEC.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_NEC.cpp
@@ -44,7 +44,7 @@ void IRsend::sendNEC(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// A raw 32-bit NEC message.
//
-// Status: BETA / Expected to work.
+// Status: STABLE / Expected to work.
//
// Ref:
// http://www.sbprojects.com/knowledge/ir/nec.php
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_NEC.h b/lib/IRremoteESP8266-2.7.5/src/ir_NEC.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_NEC.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_NEC.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Neoclima.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Neoclima.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.cpp
index 0e410ca67..8c93ef26f 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Neoclima.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.cpp
@@ -470,7 +470,7 @@ String IRNeoclimaAc::toString(void) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Known working
+// Status: STABLE / Known working
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/764
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Neoclima.h b/lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Neoclima.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Neoclima.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Nikai.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Nikai.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Nikai.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Nikai.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Panasonic.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Panasonic.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.cpp
index bf472de88..d8b627c9f 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Panasonic.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.cpp
@@ -82,7 +82,7 @@ using irutils::setBits;
// nbits: The number of bits of the message to be sent. (kPanasonicBits).
// repeat: The number of times the command is to be repeated.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Should be working.
//
// Note:
// This protocol is a modified version of Kaseikyo.
@@ -121,7 +121,7 @@ void IRsend::sendPanasonic(const uint16_t address, const uint32_t data,
// Returns:
// A raw uint64_t Panasonic message.
//
-// Status: BETA / Should be working..
+// Status: STABLE / Should be working..
//
// Note:
// Panasonic 48-bit protocol is a modified version of Kaseikyo.
@@ -149,7 +149,7 @@ uint64_t IRsend::encodePanasonic(const uint16_t manufacturer,
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Should be working.
// Note:
// Panasonic 48-bit protocol is a modified version of Kaseikyo.
// Ref:
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Panasonic.h b/lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Panasonic.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Panasonic.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Pioneer.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Pioneer.cpp
similarity index 97%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Pioneer.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Pioneer.cpp
index 85343a117..08bbf3c06 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Pioneer.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Pioneer.cpp
@@ -41,7 +41,7 @@ const uint32_t kPioneerMinGap = kPioneerMinGapTicks * kPioneerTick;
// Typically kPioneerBits.
// repeat: The number of times the command is to be repeated.
//
-// Status: BETA / Expected to be working.
+// Status: STABLE / Expected to be working.
//
// Ref:
// http://adrian-kingston.com/IRFormatPioneer.htm
@@ -75,7 +75,7 @@ void IRsend::sendPioneer(const uint64_t data, const uint16_t nbits,
// Returns:
// A raw 64-bit Pioneer message code.
//
-// Status: BETA / Expected to work.
+// Status: STABLE / Expected to work.
//
// Note:
// Address & Command can be take from a decode result OR from the spreadsheets
@@ -103,7 +103,7 @@ uint64_t IRsend::encodePioneer(const uint16_t address, const uint16_t command) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Should be working. (Self decodes & real examples)
+// Status: STABLE / Should be working. (Self decodes & real examples)
//
bool IRrecv::decodePioneer(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Pronto.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Pronto.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Pronto.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Pronto.cpp
index a408afed5..6b7a779de 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Pronto.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Pronto.cpp
@@ -21,7 +21,7 @@ const uint16_t kProntoDataOffset = 4;
// len: Nr. of entries in the data[] array.
// repeat: Nr. of times to repeat the message.
//
-// Status: ALPHA / Not tested in the real world.
+// Status: STABLE / Known working.
//
// Note:
// Pronto codes are typically represented in hexadecimal.
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_RC5_RC6.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_RC5_RC6.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_RC5_RC6.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_RC5_RC6.cpp
index ce69aaa3a..370100f9e 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_RC5_RC6.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_RC5_RC6.cpp
@@ -184,7 +184,7 @@ uint64_t IRsend::toggleRC5(uint64_t data) { return data ^ kRc5ToggleMask; }
// Returns:
// A data message suitable for use in sendRC6() with the toggle bit flipped.
//
-// Status: BETA / Should work fine.
+// Status: STABLE / Should work fine.
//
// Ref:
// http://www.sbprojects.com/knowledge/ir/rc6.php
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_RCMM.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_RCMM.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/src/ir_RCMM.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_RCMM.cpp
index a2542e467..ea0e05e9d 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_RCMM.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_RCMM.cpp
@@ -45,7 +45,7 @@ const uint16_t kRcmmExcess = 50;
// nbits: The number of bits of data to send. (Typically 12, 24, or 32[Nokia])
// repeat: The nr. of times the message should be sent.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Should be working.
//
// Ref:
// http://www.sbprojects.com/knowledge/ir/rcmm.php
@@ -102,7 +102,7 @@ void IRsend::sendRCMM(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Should be working.
//
// Ref:
// http://www.sbprojects.com/knowledge/ir/rcmm.php
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Samsung.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Samsung.cpp
similarity index 93%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Samsung.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Samsung.cpp
index a31e76953..78b36e146 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Samsung.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Samsung.cpp
@@ -72,7 +72,7 @@ using irutils::setBits;
// nbits: The bit size of the message being sent. typically kSamsungBits.
// repeat: The number of times the message is to be repeated.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Should be working.
//
// Ref: http://elektrolab.wz.cz/katalog/samsung_protocol.pdf
void IRsend::sendSAMSUNG(const uint64_t data, const uint16_t nbits,
@@ -92,7 +92,7 @@ void IRsend::sendSAMSUNG(const uint64_t data, const uint16_t nbits,
// Returns:
// A raw 32-bit Samsung message suitable for sendSAMSUNG().
//
-// Status: BETA / Should be working.
+// Status: STABLE / Should be working.
uint32_t IRsend::encodeSAMSUNG(const uint8_t customer, const uint8_t command) {
uint8_t revcustomer = reverseBits(customer, sizeof(customer) * 8);
uint8_t revcommand = reverseBits(command, sizeof(command) * 8);
@@ -271,7 +271,7 @@ bool IRrecv::decodeSamsung36(decode_results *results, uint16_t offset,
// https://github.com/crankyoldgit/IRremoteESP8266/issues/505
void IRsend::sendSamsungAC(const uint8_t data[], const uint16_t nbytes,
const uint16_t repeat) {
- if (nbytes < kSamsungAcStateLength && nbytes % kSamsungACSectionLength)
+ if (nbytes < kSamsungAcStateLength && nbytes % kSamsungAcSectionLength)
return; // Not an appropriate number of bytes to send a proper message.
enableIROut(38);
@@ -281,11 +281,11 @@ void IRsend::sendSamsungAC(const uint8_t data[], const uint16_t nbytes,
space(kSamsungAcHdrSpace);
// Send in 7 byte sections.
for (uint16_t offset = 0; offset < nbytes;
- offset += kSamsungACSectionLength) {
+ offset += kSamsungAcSectionLength) {
sendGeneric(kSamsungAcSectionMark, kSamsungAcSectionSpace,
kSamsungAcBitMark, kSamsungAcOneSpace, kSamsungAcBitMark,
kSamsungAcZeroSpace, kSamsungAcBitMark, kSamsungAcSectionGap,
- data + offset, kSamsungACSectionLength, // 7 bytes == 56 bits
+ data + offset, kSamsungAcSectionLength, // 7 bytes == 56 bits
38000, false, 0, 50); // Send in LSBF order
}
// Complete made up guess at inter-message gap.
@@ -379,10 +379,10 @@ void IRSamsungAc::sendExtended(const uint16_t repeat, const bool calcchecksum) {
0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// Copy/convert the internal state to an extended state.
- for (uint16_t i = 0; i < kSamsungACSectionLength; i++)
+ for (uint16_t i = 0; i < kSamsungAcSectionLength; i++)
extended_state[i] = remote_state[i];
- for (uint16_t i = kSamsungACSectionLength; i < kSamsungAcStateLength; i++)
- extended_state[i + kSamsungACSectionLength] = remote_state[i];
+ for (uint16_t i = kSamsungAcSectionLength; i < kSamsungAcStateLength; i++)
+ extended_state[i + kSamsungAcSectionLength] = remote_state[i];
// extended_state[8] seems special. This is a guess on how to calculate it.
extended_state[8] = (extended_state[1] & 0x9F) | 0x40;
// Send it.
@@ -425,7 +425,7 @@ void IRSamsungAc::setRaw(const uint8_t new_code[], const uint16_t length) {
// Shrink the extended state into a normal state.
if (length > kSamsungAcStateLength) {
for (uint8_t i = kSamsungAcStateLength; i < length; i++)
- remote_state[i - kSamsungACSectionLength] = remote_state[i];
+ remote_state[i - kSamsungAcSectionLength] = remote_state[i];
}
}
@@ -550,14 +550,15 @@ void IRSamsungAc::setQuiet(const bool on) {
bool IRSamsungAc::getPowerful(void) {
return !(remote_state[8] & kSamsungAcPowerfulMask8) &&
- GETBITS8(remote_state[10], kSamsungAcPowerful10Offset,
- kSamsungAcPowerful10Offset) &&
+ (GETBITS8(remote_state[10], kSamsungAcPowerful10Offset,
+ kSamsungAcPowerful10Size) == kSamsungAcPowerful10On) &&
(this->getFan() == kSamsungAcFanTurbo);
}
void IRSamsungAc::setPowerful(const bool on) {
+ uint8_t off_value = this->getBreeze() ? kSamsungAcBreezeOn : 0b000;
setBits(&remote_state[10], kSamsungAcPowerful10Offset,
- kSamsungAcPowerful10Offset, on ? 0b11: 0b00);
+ kSamsungAcPowerful10Size, on ? kSamsungAcPowerful10On : off_value);
if (on) {
remote_state[8] &= ~kSamsungAcPowerfulMask8; // Bit needs to be cleared.
// Powerful mode sets fan speed to Turbo.
@@ -570,6 +571,26 @@ void IRSamsungAc::setPowerful(const bool on) {
}
}
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
+// Are the vanes closed over the fan outlet, to stop direct wind? Aka. WindFree
+bool IRSamsungAc::getBreeze(void) {
+ return (GETBITS8(remote_state[10], kSamsungAcBreezeOffset,
+ kSamsungAcBreezeSize) == kSamsungAcBreezeOn) &&
+ (this->getFan() == kSamsungAcFanAuto && !getSwing());
+}
+
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
+// Closes the vanes over the fan outlet, to stop direct wind. Aka. WindFree
+void IRSamsungAc::setBreeze(const bool on) {
+ uint8_t off_value = this->getPowerful() ? kSamsungAcPowerful10On : 0b000;
+ setBits(&remote_state[10], kSamsungAcBreezeOffset,
+ kSamsungAcBreezeSize, on ? kSamsungAcBreezeOn : off_value);
+ if (on) {
+ this->setFan(kSamsungAcFanAuto);
+ this->setSwing(false);
+ }
+}
+
bool IRSamsungAc::getDisplay(void) {
return GETBIT8(remote_state[10], kSamsungAcDisplayOffset);
}
@@ -695,6 +716,7 @@ String IRSamsungAc::toString(void) {
result += addBoolToString(getClean(), kCleanStr);
result += addBoolToString(getQuiet(), kQuietStr);
result += addBoolToString(getPowerful(), kPowerfulStr);
+ result += addBoolToString(getBreeze(), kBreezeStr);
result += addBoolToString(getDisplay(), kLightStr);
result += addBoolToString(getIon(), kIonStr);
return result;
@@ -726,17 +748,17 @@ bool IRrecv::decodeSamsungAC(decode_results *results, uint16_t offset,
if (!matchMark(results->rawbuf[offset++], kSamsungAcBitMark)) return false;
if (!matchSpace(results->rawbuf[offset++], kSamsungAcHdrSpace)) return false;
// Section(s)
- for (uint16_t pos = 0; pos <= (nbits / 8) - kSamsungACSectionLength;
- pos += kSamsungACSectionLength) {
+ for (uint16_t pos = 0; pos <= (nbits / 8) - kSamsungAcSectionLength;
+ pos += kSamsungAcSectionLength) {
uint16_t used;
// Section Header + Section Data (7 bytes) + Section Footer
used = matchGeneric(results->rawbuf + offset, results->state + pos,
- results->rawlen - offset, kSamsungACSectionLength * 8,
+ results->rawlen - offset, kSamsungAcSectionLength * 8,
kSamsungAcSectionMark, kSamsungAcSectionSpace,
kSamsungAcBitMark, kSamsungAcOneSpace,
kSamsungAcBitMark, kSamsungAcZeroSpace,
kSamsungAcBitMark, kSamsungAcSectionGap,
- pos + kSamsungACSectionLength >= nbits / 8,
+ pos + kSamsungAcSectionLength >= nbits / 8,
_tolerance, 0, false);
if (used == 0) return false;
offset += used;
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Samsung.h b/lib/IRremoteESP8266-2.7.5/src/ir_Samsung.h
similarity index 70%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Samsung.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Samsung.h
index 52a781b65..31b5ea181 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Samsung.h
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Samsung.h
@@ -19,22 +19,59 @@
// Supports:
// Brand: Samsung, Model: UA55H6300 TV
// Brand: Samsung, Model: DB63-03556X003 remote
+// Brand: Samsung, Model: DB93-16761C remote
// Brand: Samsung, Model: IEC-R03 remote
// Brand: Samsung, Model: AR09FSSDAWKNFA A/C
// Brand: Samsung, Model: AR12KSFPEWQNET A/C
// Brand: Samsung, Model: AR12HSSDBWKNEU A/C
+// Brand: Samsung, Model: AR12NXCXAWKXEU A/C
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/505
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
// Constants
+// Byte[1]
+// Checksum 0b11110000 ???
+const uint8_t kSamsungAcPower1Offset = 5; // Mask 0b00100000
+const uint8_t kSamsungAcQuiet1Offset = 4; // Mask 0b00010000
+// Byte[5]
+const uint8_t kSamsungAcQuiet5Offset = 5;
+// Byte[6]
+const uint8_t kSamsungAcPower6Offset = 4; // Mask 0b00110000
+const uint8_t kSamsungAcPower6Size = 2; // Bits
+// Byte[8]
+// Checksum 0b11110000 ???
+const uint8_t kSamsungAcPowerfulMask8 = 0b01010000;
+// Byte[9]
+const uint8_t kSamsungAcSwingOffset = 4; // Mask 0b01110000
+const uint8_t kSamsungAcSwingSize = 3; // Bits
+const uint8_t kSamsungAcSwingMove = 0b010;
+const uint8_t kSamsungAcSwingStop = 0b111;
+// Byte[10]
+const uint8_t kSamsungAcPowerful10Offset = 1; // Mask 0b00001110
+const uint8_t kSamsungAcPowerful10Size = 3; // Mask 0b00001110
+const uint8_t kSamsungAcPowerful10On = 0b011;
+// Breeze (aka. WindFree)
+const uint8_t kSamsungAcBreezeOffset = kSamsungAcPowerful10Offset;
+const uint8_t kSamsungAcBreezeSize = kSamsungAcPowerful10Size;
+const uint8_t kSamsungAcBreezeOn = 0b101;
+const uint8_t kSamsungAcDisplayOffset = 4; // Mask 0b00010000
+const uint8_t kSamsungAcClean10Offset = 7; // Mask 0b10000000
+// Byte[11]
+const uint8_t kSamsungAcIonOffset = 0; // Mask 0b00000001
+const uint8_t kSamsungAcClean11Offset = 1; // Mask 0b00000010
+const uint8_t kSamsungAcMinTemp = 16; // C Mask 0b11110000
+const uint8_t kSamsungAcMaxTemp = 30; // C Mask 0b11110000
+const uint8_t kSamsungAcAutoTemp = 25; // C Mask 0b11110000
+// Byte[12]
+const uint8_t kSamsungAcModeOffset = 4; // Mask 0b01110000
const uint8_t kSamsungAcAuto = 0;
const uint8_t kSamsungAcCool = 1;
const uint8_t kSamsungAcDry = 2;
const uint8_t kSamsungAcFan = 3;
const uint8_t kSamsungAcHeat = 4;
-const uint8_t kSamsungAcModeOffset = 4; // Mask 0b01110000
-const uint8_t kSamsungAcFanOffest = 1; // Mask 0b00001110
+const uint8_t kSamsungAcFanOffest = 1; // Mask 0b00001110
const uint8_t kSamsungAcFanSize = 3; // Bits
const uint8_t kSamsungAcFanAuto = 0;
const uint8_t kSamsungAcFanLow = 2;
@@ -42,28 +79,10 @@ const uint8_t kSamsungAcFanMed = 4;
const uint8_t kSamsungAcFanHigh = 5;
const uint8_t kSamsungAcFanAuto2 = 6;
const uint8_t kSamsungAcFanTurbo = 7;
-const uint8_t kSamsungAcMinTemp = 16; // 16C
-const uint8_t kSamsungAcMaxTemp = 30; // 30C
-const uint8_t kSamsungAcAutoTemp = 25; // 25C
-const uint8_t kSamsungAcPower1Offset = 5;
-const uint8_t kSamsungAcPower6Offset = 4; // Mask 0b00110000
-const uint8_t kSamsungAcPower6Size = 2; // Bits
-const uint8_t kSamsungAcSwingOffset = 4; // Mask 0b01110000
-const uint8_t kSamsungAcSwingSize = 3; // Bits
-const uint8_t kSamsungAcSwingMove = 0b010;
-const uint8_t kSamsungAcSwingStop = 0b111;
-const uint8_t kSamsungAcBeepOffset = 1;
-const uint8_t kSamsungAcClean10Offset = 7;
-const uint8_t kSamsungAcClean11Offset = 1; // 0b00000010
-const uint8_t kSamsungAcQuiet1Offset = 4;
-const uint8_t kSamsungAcQuiet5Offset = 5;
-const uint8_t kSamsungAcPowerfulMask8 = 0b01010000;
-const uint8_t kSamsungAcPowerful10Offset = 1; // Mask 0b00000110
-const uint8_t kSamsungAcPowerful10Size = 1; // Mask 0b00000110
-const uint8_t kSamsungAcDisplayOffset = 4; // Mask 0b00010000
-const uint8_t kSamsungAcIonOffset = 0; // Mask 0b00000001
+// Byte[13]
+const uint8_t kSamsungAcBeepOffset = 1; // Mask 0b00000010
-const uint16_t kSamsungACSectionLength = 7;
+const uint16_t kSamsungAcSectionLength = 7;
const uint64_t kSamsungAcPowerSection = 0x1D20F00000000;
// Classes
@@ -103,7 +122,8 @@ class IRSamsungAc {
bool getQuiet(void);
void setPowerful(const bool on);
bool getPowerful(void);
-
+ void setBreeze(const bool on);
+ bool getBreeze(void);
void setDisplay(const bool on);
bool getDisplay(void);
void setIon(const bool on);
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Sanyo.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Sanyo.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Sanyo.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Sanyo.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Sharp.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.cpp
similarity index 93%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Sharp.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Sharp.cpp
index f28ca0f4d..363271012 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Sharp.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.cpp
@@ -16,6 +16,7 @@
// Equipment it seems compatible with:
// * Sharp LC-52D62U
+// * Sharp AH-AxSAY A/C (Remote CRMC-A907 JBEZ)
// *
//
@@ -56,7 +57,7 @@ using irutils::setBits;
// nbits: Nr. of bits of data to be sent. Typically kSharpBits.
// repeat: Nr. of additional times the message is to be sent.
//
-// Status: BETA / Previously working fine.
+// Status: STABLE / Working fine.
//
// Notes:
// This procedure handles the inversion of bits required per protocol.
@@ -102,7 +103,7 @@ void IRsend::sendSharpRaw(const uint64_t data, const uint16_t nbits,
// Returns:
// An uint32_t containing the raw Sharp message for sendSharpRaw().
//
-// Status: BETA / Should work okay.
+// Status: STABLE / Works okay.
//
// Notes:
// Assumes the standard Sharp bit sizes.
@@ -334,18 +335,51 @@ void IRSharpAc::setRaw(const uint8_t new_code[], const uint16_t length) {
memcpy(remote, new_code, std::min(length, kSharpAcStateLength));
}
+void IRSharpAc::setPreviousPower(const bool on) {
+ setBit(&remote[kSharpAcBytePower], kSharpAcBitPreviousPowerOffset, on);
+}
+
+bool IRSharpAc::getPreviousPower(void) {
+ return GETBIT8(remote[kSharpAcBytePower], kSharpAcBitPreviousPowerOffset);
+}
+
void IRSharpAc::on(void) { setPower(true); }
void IRSharpAc::off(void) { setPower(false); }
void IRSharpAc::setPower(const bool on) {
+ setPreviousPower(getPower());
setBit(&remote[kSharpAcBytePower], kSharpAcBitPowerOffset, on);
+ setButton(kSharpAcButtonPowerMode);
+}
+
+void IRSharpAc::setPower(const bool on, const bool prev) {
+ setPower(on);
+ setPreviousPower(prev);
}
bool IRSharpAc::getPower(void) {
return GETBIT8(remote[kSharpAcBytePower], kSharpAcBitPowerOffset);
}
+void IRSharpAc::setButton(const uint8_t button) {
+ switch (button) {
+ case kSharpAcButtonPowerMode:
+ case kSharpAcButtonTemp:
+ case kSharpAcButtonFan:
+ setBits(&remote[kSharpAcByteButton], kSharpAcButtonOffset,
+ kSharpAcButtonSize, button);
+ break;
+ default:
+ setButton(kSharpAcButtonPowerMode);
+ }
+}
+
+uint8_t IRSharpAc::getButton(void) {
+ return GETBITS8(remote[kSharpAcByteButton], kSharpAcButtonOffset,
+ kSharpAcButtonSize);
+}
+
// Set the temp in deg C
void IRSharpAc::setTemp(const uint8_t temp) {
switch (this->getMode()) {
@@ -353,16 +387,15 @@ void IRSharpAc::setTemp(const uint8_t temp) {
case kSharpAcAuto:
case kSharpAcDry:
remote[kSharpAcByteTemp] = 0;
- remote[kSharpAcByteManual] = 0; // When in Dry/Auto this byte is 0.
return;
default:
remote[kSharpAcByteTemp] = 0xC0;
- setBit(&remote[kSharpAcByteManual], kSharpAcBitTempManualOffset);
}
uint8_t degrees = std::max(temp, kSharpAcMinTemp);
degrees = std::min(degrees, kSharpAcMaxTemp);
setBits(&remote[kSharpAcByteTemp], kLowNibble, kNibbleSize,
degrees - kSharpAcMinTemp);
+ setButton(kSharpAcButtonTemp);
}
uint8_t IRSharpAc::getTemp(void) {
@@ -375,11 +408,10 @@ uint8_t IRSharpAc::getMode(void) {
}
void IRSharpAc::setMode(const uint8_t mode) {
- setBit(&remote[kSharpAcBytePower], kSharpAcBitModeNonAutoOffset,
- mode != kSharpAcAuto);
switch (mode) {
case kSharpAcAuto:
case kSharpAcDry:
+ this->setFan(2); // When Dry or Auto, Fan always 2(Auto)
this->setTemp(0); // Dry/Auto have no temp setting.
// FALLTHRU
case kSharpAcCool:
@@ -389,6 +421,7 @@ void IRSharpAc::setMode(const uint8_t mode) {
default:
this->setMode(kSharpAcAuto);
}
+ setButton(kSharpAcButtonPowerMode);
}
// Set the speed of the fan
@@ -399,14 +432,13 @@ void IRSharpAc::setFan(const uint8_t speed) {
case kSharpAcFanMed:
case kSharpAcFanHigh:
case kSharpAcFanMax:
- setBit(&remote[kSharpAcByteManual], kSharpAcBitFanManualOffset,
- speed != kSharpAcFanAuto);
setBits(&remote[kSharpAcByteFan], kSharpAcFanOffset, kSharpAcFanSize,
speed);
break;
default:
this->setFan(kSharpAcFanAuto);
}
+ setButton(kSharpAcButtonFan);
}
uint8_t IRSharpAc::getFan(void) {
@@ -485,8 +517,9 @@ stdAc::state_t IRSharpAc::toCommon(void) {
// Convert the internal state into a human readable string.
String IRSharpAc::toString(void) {
String result = "";
- result.reserve(60); // Reserve some heap for the string to reduce fragging.
+ result.reserve(80); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), kPowerStr, false);
+ result += addBoolToString(getPreviousPower(), kPreviousPowerStr);
result += addModeToString(getMode(), kSharpAcAuto, kSharpAcCool, kSharpAcHeat,
kSharpAcDry, kSharpAcAuto);
result += addTempToString(getTemp());
@@ -506,7 +539,7 @@ String IRSharpAc::toString(void) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Known working.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/638
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Sharp.h b/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.h
similarity index 81%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Sharp.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Sharp.h
index e1c81c3a2..03d27d44f 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Sharp.h
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Sharp.h
@@ -3,6 +3,7 @@
// Supports:
// Brand: Sharp, Model: LC-52D62U TV
// Brand: Sharp, Model: AY-ZP40KR A/C
+// Brand: Sharp, Model: AH-AxSAY A/C
#ifndef IR_SHARP_H_
#define IR_SHARP_H_
@@ -38,17 +39,19 @@ const uint8_t kSharpAcFanHigh = 0b101; // 5 (FAN3)
const uint8_t kSharpAcFanMax = 0b111; // 7 (FAN4)
const uint8_t kSharpAcByteTemp = 4;
const uint8_t kSharpAcBytePower = 5;
-const uint8_t kSharpAcBitPowerOffset = 4;
-const uint8_t kSharpAcBitModeNonAutoOffset = 5; // 0b00100000
+const uint8_t kSharpAcBitPowerOffset = 4; // 0b000x0000
+const uint8_t kSharpAcBitPreviousPowerOffset = 5; // 0b00x00000
const uint8_t kSharpAcByteMode = 6;
const uint8_t kSharpAcModeSize = 2; // Mask 0b00000011;
const uint8_t kSharpAcByteFan = kSharpAcByteMode;
const uint8_t kSharpAcFanOffset = 4; // Mask 0b01110000
const uint8_t kSharpAcFanSize = 3; // Nr. of Bits
-const uint8_t kSharpAcByteManual = 10;
-const uint8_t kSharpAcBitFanManualOffset = 0; // 0b00000001
-const uint8_t kSharpAcBitTempManualOffset = 2; // 0b00000100
-
+const uint8_t kSharpAcByteButton = 10;
+const uint8_t kSharpAcButtonOffset = 0;
+const uint8_t kSharpAcButtonSize = 3; // Mask 0b00000xxx
+const uint8_t kSharpAcButtonPowerMode = 0b000; // 0
+const uint8_t kSharpAcButtonTemp = 0b100; // 4
+const uint8_t kSharpAcButtonFan = 0b101; // 5
class IRSharpAc {
public:
@@ -63,13 +66,18 @@ class IRSharpAc {
void on(void);
void off(void);
void setPower(const bool on);
+ void setPower(const bool on, const bool prev);
bool getPower(void);
+ void setPreviousPower(const bool on);
+ bool getPreviousPower(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 setButton(const uint8_t button);
+ uint8_t getButton(void);
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[],
const uint16_t length = kSharpAcStateLength);
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Sherwood.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Sherwood.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Sherwood.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Sherwood.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Sony.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Sony.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Sony.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Sony.cpp
index c346eb293..9ff0c50cc 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Sony.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Sony.cpp
@@ -106,7 +106,7 @@ void IRsend::_sendSony(uint64_t data, uint16_t nbits, uint16_t repeat,
// Returns:
// A sendSony compatible data message.
//
-// Status: BETA / Should be working.
+// Status: STABLE / Should be working.
uint32_t IRsend::encodeSony(uint16_t nbits, uint16_t command, uint16_t address,
uint16_t extended) {
uint32_t result = 0;
@@ -141,7 +141,7 @@ uint32_t IRsend::encodeSony(uint16_t nbits, uint16_t command, uint16_t address,
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Should be working. strict mode is ALPHA / Untested.
+// Status: STABLE / Should be working. strict mode is ALPHA / Untested.
//
// Notes:
// SONY protocol, SIRC (Serial Infra-Red Control) can be 12,15,20 bits long.
diff --git a/lib/IRremoteESP8266-2.7.5/src/ir_Symphony.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Symphony.cpp
new file mode 100644
index 000000000..f0194fdb8
--- /dev/null
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Symphony.cpp
@@ -0,0 +1,87 @@
+// Copyright 2020 David Conran
+
+// Send & decode support for Symphony added by David Conran
+
+// Supports:
+// Brand: Symphony, Model: Air Cooler 3Di
+
+#include
+#include "IRrecv.h"
+#include "IRsend.h"
+#include "IRtimer.h"
+#include "IRutils.h"
+
+// Constants
+// Ref:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1057
+const uint16_t kSymphonyZeroMark = 1250;
+const uint16_t kSymphonyZeroSpace = 400;
+const uint16_t kSymphonyOneMark = kSymphonyZeroSpace;
+const uint16_t kSymphonyOneSpace = kSymphonyZeroMark;
+const uint16_t kSymphonyFooterMark = kSymphonyOneMark;
+const uint32_t kSymphonyFooterGap = 8000;
+
+#if SEND_SYMPHONY
+// Send a Symphony packet.
+//
+// Args:
+// data: The data we want to send. MSB first.
+// nbits: The number of bits of data to send. (Typically 12, 24, or 32[Nokia])
+// repeat: The nr. of times the message should be sent.
+//
+// Status: STABLE / Should be working.
+//
+// Ref:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1057
+void IRsend::sendSymphony(uint64_t data, uint16_t nbits, uint16_t repeat) {
+ sendGeneric(0, 0,
+ kSymphonyOneMark, kSymphonyOneSpace,
+ kSymphonyZeroMark, kSymphonyZeroSpace,
+ kSymphonyFooterMark, kSymphonyFooterGap,
+ data, nbits, 38000, true, repeat, kDutyDefault);
+}
+#endif // SEND_SYMPHONY
+
+#if DECODE_SYMPHONY
+// Decode a Symphony packet if possible.
+// Places successful decode information in the results pointer.
+// Args:
+// results: Ptr to the data to decode and where to store the decode result.
+// offset: The starting index to use when attempting to decode the raw data.
+// Typically/Defaults to kStartOffset.
+// nbits: Nr. of bits to expect in the data portion. Typically kSymphonyBits
+// 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: STABLE / Should be working.
+//
+// Ref:
+//
+bool IRrecv::decodeSymphony(decode_results *results, uint16_t offset,
+ const uint16_t nbits, const bool strict) {
+ uint64_t data = 0;
+
+ if (results->rawlen < 2 * nbits + kFooter + offset - 1)
+ return false; // Not enough entries to ever be SYMPHONY.
+ // Compliance
+ if (strict && nbits != kSymphonyBits) return false;
+
+ if (!matchGeneric(results->rawbuf + offset, &data, results->rawlen - offset,
+ nbits,
+ 0, 0, // No Header
+ kSymphonyOneMark, kSymphonyOneSpace,
+ kSymphonyZeroMark, kSymphonyZeroSpace,
+ kSymphonyFooterMark, kSymphonyFooterGap, true,
+ _tolerance, 0))
+ return false;
+
+ // Success
+ results->value = data;
+ results->decode_type = decode_type_t::SYMPHONY;
+ results->bits = nbits;
+ results->address = 0;
+ results->command = 0;
+ return true;
+}
+#endif // DECODE_SYMPHONY
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Tcl.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Tcl.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Tcl.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Tcl.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Tcl.h b/lib/IRremoteESP8266-2.7.5/src/ir_Tcl.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Tcl.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Tcl.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Teco.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Teco.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Teco.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Teco.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Teco.h b/lib/IRremoteESP8266-2.7.5/src/ir_Teco.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Teco.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Teco.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Toshiba.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Toshiba.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Toshiba.h b/lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Toshiba.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Toshiba.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Trotec.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Trotec.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Trotec.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Trotec.cpp
index 563564d36..d8b87e034 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Trotec.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Trotec.cpp
@@ -245,7 +245,7 @@ String IRTrotecESP::toString(void) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA / Probably works. Untested on real devices.
+// Status: STABLE / Works. Untested on real devices.
//
// Ref:
bool IRrecv::decodeTrotec(decode_results *results, uint16_t offset,
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Trotec.h b/lib/IRremoteESP8266-2.7.5/src/ir_Trotec.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Trotec.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Trotec.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Vestel.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Vestel.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Vestel.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Vestel.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Vestel.h b/lib/IRremoteESP8266-2.7.5/src/ir_Vestel.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Vestel.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Vestel.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Whirlpool.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Whirlpool.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.cpp
index e1ca2e6db..3ba781c4c 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Whirlpool.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.cpp
@@ -56,7 +56,7 @@ using irutils::setBits;
// nbytes: Nr. of bytes of data in the array. (>=kWhirlpoolAcStateLength)
// repeat: Nr. of times the message is to be repeated. (Default = 0).
//
-// Status: ALPHA / Untested.
+// Status: BETA / Probably works.
//
// Ref:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/509
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Whirlpool.h b/lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Whirlpool.h
rename to lib/IRremoteESP8266-2.7.5/src/ir_Whirlpool.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/ir_Whynter.cpp b/lib/IRremoteESP8266-2.7.5/src/ir_Whynter.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/src/ir_Whynter.cpp
rename to lib/IRremoteESP8266-2.7.5/src/ir_Whynter.cpp
index 118eb7559..92bad25ce 100644
--- a/lib/IRremoteESP8266-2.7.4/src/ir_Whynter.cpp
+++ b/lib/IRremoteESP8266-2.7.5/src/ir_Whynter.cpp
@@ -76,7 +76,7 @@ void IRsend::sendWhynter(uint64_t data, uint16_t nbits, uint16_t repeat) {
// Returns:
// boolean: True if it can decode it, false if it can't.
//
-// Status: BETA Strict mode is ALPHA.
+// Status: STABLE / Working. Strict mode is ALPHA.
//
// Ref:
// https://github.com/z3t0/Arduino-IRremote/blob/master/ir_Whynter.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/README.md b/lib/IRremoteESP8266-2.7.5/src/locale/README.md
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/locale/README.md
rename to lib/IRremoteESP8266-2.7.5/src/locale/README.md
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/de-CH.h b/lib/IRremoteESP8266-2.7.5/src/locale/de-CH.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/locale/de-CH.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/de-CH.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/de-DE.h b/lib/IRremoteESP8266-2.7.5/src/locale/de-DE.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/locale/de-DE.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/de-DE.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/defaults.h b/lib/IRremoteESP8266-2.7.5/src/locale/defaults.h
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/src/locale/defaults.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/defaults.h
index 20e38082a..509e35cfe 100644
--- a/lib/IRremoteESP8266-2.7.4/src/locale/defaults.h
+++ b/lib/IRremoteESP8266-2.7.5/src/locale/defaults.h
@@ -24,6 +24,9 @@
#ifndef D_STR_POWER
#define D_STR_POWER "Power"
#endif // D_STR_POWER
+#ifndef D_STR_PREVIOUS
+#define D_STR_PREVIOUS "Previous"
+#endif // D_STR_PREVIOUS
#ifndef D_STR_ON
#define D_STR_ON "On"
#endif // D_STR_ON
@@ -363,6 +366,9 @@
#ifndef D_STR_POWERTOGGLE
#define D_STR_POWERTOGGLE D_STR_POWER " " D_STR_TOGGLE
#endif // D_STR_POWERTOGGLE
+#ifndef D_STR_PREVIOUSPOWER
+#define D_STR_PREVIOUSPOWER D_STR_PREVIOUS " " D_STR_POWER
+#endif // D_STR_PREVIOUSPOWER
#ifndef D_STR_SENSORTEMP
#define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP
#endif // D_STR_SENSORTEMP
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/en-AU.h b/lib/IRremoteESP8266-2.7.5/src/locale/en-AU.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/locale/en-AU.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/en-AU.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/en-IE.h b/lib/IRremoteESP8266-2.7.5/src/locale/en-IE.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/locale/en-IE.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/en-IE.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/en-UK.h b/lib/IRremoteESP8266-2.7.5/src/locale/en-UK.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/locale/en-UK.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/en-UK.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/en-US.h b/lib/IRremoteESP8266-2.7.5/src/locale/en-US.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/src/locale/en-US.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/en-US.h
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/es-ES.h b/lib/IRremoteESP8266-2.7.5/src/locale/es-ES.h
similarity index 97%
rename from lib/IRremoteESP8266-2.7.4/src/locale/es-ES.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/es-ES.h
index 821186141..52f22333d 100644
--- a/lib/IRremoteESP8266-2.7.4/src/locale/es-ES.h
+++ b/lib/IRremoteESP8266-2.7.5/src/locale/es-ES.h
@@ -7,6 +7,8 @@
#define D_STR_UNKNOWN "DESCONOCIDO"
#define D_STR_PROTOCOL "Protocolo"
#define D_STR_POWER "Poder"
+#define D_STR_PREVIOUS "Anterior"
+#define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
#define D_STR_ON "Encendido"
#define D_STR_OFF "Apagado"
#define D_STR_MODE "Modo"
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/fr-FR.h b/lib/IRremoteESP8266-2.7.5/src/locale/fr-FR.h
similarity index 97%
rename from lib/IRremoteESP8266-2.7.4/src/locale/fr-FR.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/fr-FR.h
index 5ab10cb62..0eae39e2e 100644
--- a/lib/IRremoteESP8266-2.7.4/src/locale/fr-FR.h
+++ b/lib/IRremoteESP8266-2.7.5/src/locale/fr-FR.h
@@ -10,6 +10,8 @@
#define D_STR_SLEEP "Pause"
#define D_STR_LIGHT "Lumière"
#define D_STR_POWERFUL "Puissance"
+#define D_STR_PREVIOUS "Precedente"
+#define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
#define D_STR_QUIET "Silence"
#define D_STR_ECONO "Economie"
#define D_STR_BEEP "Bip"
diff --git a/lib/IRremoteESP8266-2.7.4/src/locale/it-IT.h b/lib/IRremoteESP8266-2.7.5/src/locale/it-IT.h
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/src/locale/it-IT.h
rename to lib/IRremoteESP8266-2.7.5/src/locale/it-IT.h
index b078a7319..b04a129d2 100644
--- a/lib/IRremoteESP8266-2.7.4/src/locale/it-IT.h
+++ b/lib/IRremoteESP8266-2.7.5/src/locale/it-IT.h
@@ -8,6 +8,8 @@
#define D_STR_UNKNOWN "SCONOSCIUTO"
#define D_STR_PROTOCOL "Protocollo"
#define D_STR_POWER "Accensione"
+#define D_STR_PREVIOUS "Precedente"
+#define D_STR_PREVIOUSPOWER D_STR_POWER " " D_STR_PREVIOUS
#define D_STR_ON "Acceso"
#define D_STR_OFF "Spento"
#define D_STR_MODE "Modalità"
diff --git a/lib/IRremoteESP8266-2.7.4/test/IRac_test.cpp b/lib/IRremoteESP8266-2.7.5/test/IRac_test.cpp
similarity index 90%
rename from lib/IRremoteESP8266-2.7.4/test/IRac_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/IRac_test.cpp
index c8c231621..8ddf98b59 100644
--- a/lib/IRremoteESP8266-2.7.4/test/IRac_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/IRac_test.cpp
@@ -54,6 +54,8 @@ TEST(TestIRac, Amcor) {
ASSERT_EQ(AMCOR, ac._irsend.capture.decode_type);
ASSERT_EQ(kAmcorBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Argo) {
@@ -103,6 +105,8 @@ TEST(TestIRac, Coolix) {
ASSERT_EQ(COOLIX, ac._irsend.capture.decode_type);
ASSERT_EQ(kCoolixBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
// Confirm we are sending with a repeat of 1. i.e. two messages.
EXPECT_EQ(
"f38000d50" // 38kHz Frequency and 50% duty-cycle.
@@ -165,6 +169,8 @@ TEST(TestIRac, Daikin) {
ASSERT_EQ(DAIKIN, ac._irsend.capture.decode_type);
ASSERT_EQ(kDaikinBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Daikin128) {
@@ -196,6 +202,8 @@ TEST(TestIRac, Daikin128) {
ASSERT_EQ(DAIKIN128, ac._irsend.capture.decode_type);
ASSERT_EQ(kDaikin128Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Daikin152) {
@@ -222,6 +230,8 @@ TEST(TestIRac, Daikin152) {
ASSERT_EQ(DAIKIN152, ac._irsend.capture.decode_type);
ASSERT_EQ(kDaikin152Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Daikin160) {
@@ -245,6 +255,8 @@ TEST(TestIRac, Daikin160) {
ASSERT_EQ(DAIKIN160, ac._irsend.capture.decode_type);
ASSERT_EQ(kDaikin160Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Daikin176) {
@@ -267,6 +279,8 @@ TEST(TestIRac, Daikin176) {
ASSERT_EQ(DAIKIN176, ac._irsend.capture.decode_type);
ASSERT_EQ(kDaikin176Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Daikin2) {
@@ -303,6 +317,8 @@ TEST(TestIRac, Daikin2) {
ASSERT_EQ(DAIKIN2, ac._irsend.capture.decode_type);
ASSERT_EQ(kDaikin2Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Daikin216) {
@@ -329,6 +345,36 @@ TEST(TestIRac, Daikin216) {
ASSERT_EQ(DAIKIN216, ac._irsend.capture.decode_type);
ASSERT_EQ(kDaikin216Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
+}
+
+TEST(TestIRac, Daikin64) {
+ IRDaikin64 ac(kGpioUnused);
+ IRac irac(kGpioUnused);
+ IRrecv capture(kGpioUnused);
+ char expected[] =
+ "Power Toggle: On, Mode: 2 (Cool), Temp: 27C, Fan: 8 (Low), "
+ "Turbo: Off, Quiet: Off, Swing(V): On, Sleep: On, "
+ "Clock: 17:59, On Timer: Off, Off Timer: Off";
+
+ ac.begin();
+ irac.daikin64(&ac,
+ true, // Power (Toggle)
+ stdAc::opmode_t::kCool, // Mode
+ 27, // Celsius
+ stdAc::fanspeed_t::kLow, // Fan Speed
+ stdAc::swingv_t::kAuto, // Veritcal swing
+ false, // Quiet
+ false, // Turbo
+ 360, // Sleep
+ 17 * 60 + 59); // Clock
+ ASSERT_EQ(expected, ac.toString());
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(capture.decode(&ac._irsend.capture));
+ ASSERT_EQ(DAIKIN64, ac._irsend.capture.decode_type);
+ ASSERT_EQ(kDaikin64Bits, ac._irsend.capture.bits);
+ ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
}
TEST(TestIRac, Electra) {
@@ -392,6 +438,8 @@ TEST(TestIRac, Fujitsu) {
ASSERT_EQ(FUJITSU_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcBits - 8, ac._irsend.capture.bits);
ASSERT_EQ(ardb1_expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
irac.fujitsu(&ac,
@@ -413,6 +461,7 @@ TEST(TestIRac, Fujitsu) {
ASSERT_EQ(FUJITSU_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcBits, ac._irsend.capture.bits);
ASSERT_EQ(arrah2e_expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
irac.fujitsu(&ac,
fujitsu_ac_remote_model_t::ARRY4, // Model
@@ -433,6 +482,7 @@ TEST(TestIRac, Fujitsu) {
ASSERT_EQ(FUJITSU_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kFujitsuAcBits, ac._irsend.capture.bits);
ASSERT_EQ(arry4_expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Goodweather) {
@@ -459,6 +509,8 @@ TEST(TestIRac, Goodweather) {
ASSERT_EQ(GOODWEATHER, ac._irsend.capture.decode_type);
ASSERT_EQ(kGoodweatherBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Gree) {
@@ -489,6 +541,8 @@ TEST(TestIRac, Gree) {
ASSERT_EQ(GREE, ac._irsend.capture.decode_type);
ASSERT_EQ(kGreeBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Haier) {
@@ -516,6 +570,8 @@ TEST(TestIRac, Haier) {
ASSERT_EQ(HAIER_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kHaierACBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
@@ -544,6 +600,8 @@ TEST(TestIRac, HaierYrwo2) {
ASSERT_EQ(HAIER_AC_YRW02, ac._irsend.capture.decode_type);
ASSERT_EQ(kHaierACYRW02Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Hitachi) {
@@ -569,6 +627,40 @@ TEST(TestIRac, Hitachi) {
ASSERT_EQ(HITACHI_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kHitachiAcBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
+}
+
+TEST(TestIRac, Hitachi1) {
+ IRHitachiAc1 ac(kGpioUnused);
+ IRac irac(kGpioUnused);
+ IRrecv capture(kGpioUnused);
+ char expected[] =
+ "Model: 1 (R-LT0541-HTA-A), Power: On, Power Toggle: Off, "
+ "Mode: 6 (Cool), Temp: 19C, Fan: 4 (Medium), "
+ "Swing(V) Toggle: On, Swing(V): On, Swing(H): On, Sleep: 2, "
+ "On Timer: Off, Off Timer: Off";
+
+ ac.begin();
+ irac.hitachi1(&ac,
+ hitachi_ac1_remote_model_t::R_LT0541_HTA_A, // Model
+ true, // Power
+ false, // Power Toggle
+ stdAc::opmode_t::kCool, // Mode
+ 19, // Celsius
+ stdAc::fanspeed_t::kMedium, // Fan speed
+ stdAc::swingv_t::kAuto, // Vertical swing
+ stdAc::swingh_t::kLeft, // Horizontal swing
+ true, // Swing toggle
+ 5 * 60 + 37); // Sleep
+
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(capture.decode(&ac._irsend.capture));
+ ASSERT_EQ(HITACHI_AC1, ac._irsend.capture.decode_type);
+ ASSERT_EQ(kHitachiAc1Bits, ac._irsend.capture.bits);
+ ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Hitachi424) {
@@ -596,6 +688,8 @@ TEST(TestIRac, Hitachi424) {
ASSERT_EQ(HITACHI_AC424, ac._irsend.capture.decode_type);
ASSERT_EQ(kHitachiAc424Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
irac.hitachi424(&ac,
@@ -611,6 +705,7 @@ TEST(TestIRac, Hitachi424) {
ASSERT_EQ(HITACHI_AC424, ac._irsend.capture.decode_type);
ASSERT_EQ(kHitachiAc424Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected_swingv, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Kelvinator) {
@@ -642,6 +737,8 @@ TEST(TestIRac, Kelvinator) {
ASSERT_EQ(KELVINATOR, ac._irsend.capture.decode_type);
ASSERT_EQ(kKelvinatorBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, LG) {
@@ -666,6 +763,8 @@ TEST(TestIRac, LG) {
ASSERT_EQ(LG, ac._irsend.capture.decode_type);
ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Midea) {
@@ -692,6 +791,8 @@ TEST(TestIRac, Midea) {
ASSERT_EQ(MIDEA, ac._irsend.capture.decode_type);
ASSERT_EQ(kMideaBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Mitsubishi) {
@@ -719,6 +820,8 @@ TEST(TestIRac, Mitsubishi) {
ASSERT_EQ(MITSUBISHI_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kMitsubishiACBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Mitsubishi136) {
@@ -743,6 +846,8 @@ TEST(TestIRac, Mitsubishi136) {
ASSERT_EQ(MITSUBISHI136, ac._irsend.capture.decode_type);
ASSERT_EQ(kMitsubishi136Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, MitsubishiHeavy88) {
@@ -771,6 +876,8 @@ TEST(TestIRac, MitsubishiHeavy88) {
ASSERT_EQ(MITSUBISHI_HEAVY_88, ac._irsend.capture.decode_type);
ASSERT_EQ(kMitsubishiHeavy88Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, MitsubishiHeavy152) {
@@ -802,6 +909,8 @@ TEST(TestIRac, MitsubishiHeavy152) {
ASSERT_EQ(MITSUBISHI_HEAVY_152, ac._irsend.capture.decode_type);
ASSERT_EQ(kMitsubishiHeavy152Bits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Neoclima) {
@@ -832,6 +941,8 @@ TEST(TestIRac, Neoclima) {
ASSERT_EQ(decode_type_t::NEOCLIMA, ac._irsend.capture.decode_type);
ASSERT_EQ(kNeoclimaBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Panasonic) {
@@ -862,6 +973,8 @@ TEST(TestIRac, Panasonic) {
ASSERT_EQ(PANASONIC_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kPanasonicAcBits, ac._irsend.capture.bits);
ASSERT_EQ(expected_nke, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
char expected_dke[] =
"Model: 3 (DKE), Power: On, Mode: 3 (Cool), Temp: 18C, Fan: 4 (High), "
@@ -887,6 +1000,7 @@ TEST(TestIRac, Panasonic) {
ASSERT_EQ(PANASONIC_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kPanasonicAcBits, ac._irsend.capture.bits);
ASSERT_EQ(expected_dke, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Samsung) {
@@ -895,7 +1009,8 @@ TEST(TestIRac, Samsung) {
IRrecv capture(0);
char expected[] =
"Power: On, Mode: 0 (Auto), Temp: 28C, Fan: 6 (Auto), Swing: On, "
- "Beep: On, Clean: On, Quiet: On, Powerful: Off, Light: On, Ion: Off";
+ "Beep: On, Clean: On, Quiet: On, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off";
ac.begin();
irac.samsung(&ac,
@@ -918,6 +1033,8 @@ TEST(TestIRac, Samsung) {
ASSERT_EQ(SAMSUNG_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kSamsungAcBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
irac.samsung(&ac,
@@ -943,8 +1060,10 @@ TEST(TestIRac, Samsung) {
// desired state.
char expected_on[] =
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off";
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off";
ASSERT_EQ(expected_on, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Sharp) {
@@ -952,11 +1071,13 @@ TEST(TestIRac, Sharp) {
IRac irac(0);
IRrecv capture(0);
char expected[] =
- "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium)";
+ "Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, "
+ "Fan: 3 (Medium)";
ac.begin();
irac.sharp(&ac,
true, // Power
+ true, // Previous Power
stdAc::opmode_t::kCool, // Mode
28, // Celsius
stdAc::fanspeed_t::kMedium); // Fan speed
@@ -966,6 +1087,8 @@ TEST(TestIRac, Sharp) {
ASSERT_EQ(SHARP_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kSharpAcBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Tcl112) {
@@ -994,6 +1117,8 @@ TEST(TestIRac, Tcl112) {
ASSERT_EQ(TCL112AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kTcl112AcBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Teco) {
@@ -1019,6 +1144,8 @@ TEST(TestIRac, Teco) {
ASSERT_EQ(TECO, ac._irsend.capture.decode_type);
ASSERT_EQ(kTecoBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Toshiba) {
@@ -1039,6 +1166,8 @@ TEST(TestIRac, Toshiba) {
ASSERT_EQ(TOSHIBA_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kToshibaACBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Trotec) {
@@ -1066,6 +1195,8 @@ TEST(TestIRac, Trotec) {
ASSERT_EQ(TROTEC, ac._irsend.capture.decode_type);
ASSERT_EQ(kTrotecBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Vestel) {
@@ -1093,6 +1224,8 @@ TEST(TestIRac, Vestel) {
ASSERT_EQ(VESTEL_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kVestelAcBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
char expected_clocks[] =
@@ -1117,6 +1250,7 @@ TEST(TestIRac, Vestel) {
ASSERT_EQ(VESTEL_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kVestelAcBits, ac._irsend.capture.bits);
ASSERT_EQ(expected_clocks, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
// Now check it sends both messages during normal operation when the
// clock is set.
@@ -1183,6 +1317,8 @@ TEST(TestIRac, Whirlpool) {
ASSERT_EQ(WHIRLPOOL_AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kWhirlpoolAcBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, cmpStates) {
@@ -1577,6 +1713,8 @@ TEST(TestIRac, Issue1001) {
"On Timer: Off, Off Timer: Off, Sleep: Off, Super: Off, "
"Command: 1 (Power)",
IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
// Now check if the mode is set to "Off" instead of just change to power off.
// i.e. How Home Assistant expects things to work.
@@ -1606,6 +1744,7 @@ TEST(TestIRac, Issue1001) {
"On Timer: Off, Off Timer: Off, Sleep: Off, Super: Off, "
"Command: 1 (Power)",
IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
// Check power switching in Daikin2 common a/c handling when from an IR message.
diff --git a/lib/IRremoteESP8266-2.7.4/test/IRrecv_test.cpp b/lib/IRremoteESP8266-2.7.5/test/IRrecv_test.cpp
similarity index 91%
rename from lib/IRremoteESP8266-2.7.4/test/IRrecv_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/IRrecv_test.cpp
index fa025a2cb..e66866be1 100644
--- a/lib/IRremoteESP8266-2.7.4/test/IRrecv_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/IRrecv_test.cpp
@@ -1589,3 +1589,107 @@ TEST(TestCrudeNoiseFilter, NoiseAtEndOfSample) {
"uint64_t data = 0x20DFC03F;\n",
resultToSourceCode(&irsend.capture));
}
+
+TEST(TestManchesterCode, matchManchester) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+
+ const uint16_t rawData[163] = {
+ 2860, 3862,
+ 1924, 1952, 1926, 1952, 956, 984, 1924, 1028, 952, 958, 980, 956, 982,
+ 1882, 1016, 950, 1958, 1920, 1948, 1004, 954, 956, 984, 956, 952, 984,
+ 974, 966, 974, 964, 974, 1888, 1010, 960, 1948, 1002, 946, 962, 978,
+ 962, 976, 960, 948, 992, 978, 1886, 982, 984, 1924, 1954, 952, 986,
+ 3892, 3862,
+ 1924, 1954, 1924, 1954, 984, 952, 1956, 996, 954, 990, 948, 958, 980,
+ 1882, 1016, 952, 1958, 1920, 1956, 994, 944, 962, 986, 956, 972, 962,
+ 976, 962, 978, 964, 952, 1908, 1010, 960, 1948, 1002, 946, 960, 978,
+ 962, 946, 990, 978, 960, 978, 1888, 1008, 954, 1952, 1928, 982, 956,
+ 3920, 3830,
+ 1946, 1934, 1954, 1922, 976, 962, 1946, 1006, 922, 990, 948, 988, 950,
+ 1910, 1008, 964, 1922, 1952, 1924, 1030, 920, 984, 954, 986, 952, 986,
+ 952, 984, 954, 986, 952, 1910, 1010, 960, 1928, 1024, 944, 996, 924,
+ 984, 954, 988, 950, 984, 954, 1910, 1008, 960, 1920, 1958, 980, 958,
+ 4800};
+ irsend.sendRaw(rawData, 163, 38);
+ irsend.makeDecodeResult();
+
+ uint16_t offset = 1;
+ uint64_t result = 0;
+ uint16_t nbits = 32;
+ EXPECT_EQ(56, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result,
+ irsend.capture.rawlen - offset, nbits,
+ 2860, 3800, 1000, 0, 3800));
+ EXPECT_EQ(0x4F2FE7E4, result);
+
+ irsend.reset();
+ irsend.sendRaw(rawData, 55, 38); // Send just the bare minimum.
+ irsend.makeDecodeResult();
+
+ EXPECT_EQ(55, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result,
+ irsend.capture.rawlen - offset, nbits,
+ 2860, 3800, 1000, 0, 3800));
+ EXPECT_EQ(0x4F2FE7E4, result);
+
+ irsend.reset();
+ irsend.sendRaw(rawData, 52, 38); // Now, just too short.
+ irsend.makeDecodeResult();
+
+ EXPECT_EQ(0, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result,
+ irsend.capture.rawlen - offset, nbits,
+ 2860, 3800, 1000, 0, 0));
+}
+
+TEST(TestManchesterCode, ManchesterLoopBackGEThomasTest) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ uint16_t offset = 1;
+ uint64_t result = 0;
+ uint16_t nbits = 32;
+ irsend.begin();
+ irsend.reset();
+ irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x12345678, nbits);
+ irsend.makeDecodeResult();
+ EXPECT_EQ(52, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result,
+ irsend.capture.rawlen - offset, nbits,
+ 5000, 7000, 1000, 0, 10000, true,
+ kUseDefTol, kMarkExcess, true, true));
+ EXPECT_EQ(0x12345678, result);
+
+ irsend.reset();
+ irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x87654321, nbits);
+ irsend.makeDecodeResult();
+ EXPECT_EQ(52, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result,
+ irsend.capture.rawlen - offset, nbits,
+ 5000, 7000, 1000, 0, 10000, true,
+ kUseDefTol, kMarkExcess, true, true));
+ EXPECT_EQ(0x87654321, result);
+}
+
+TEST(TestManchesterCode, ManchesterLoopBackIEEE802_3Test) {
+ IRsendTest irsend(0);
+ IRrecv irrecv(0);
+ uint16_t offset = 1;
+ uint64_t result = 0;
+ uint16_t nbits = 32;
+ irsend.begin();
+ irsend.reset();
+ irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x12345678, nbits, 38000,
+ true, kNoRepeat, kDutyDefault, false);
+ irsend.makeDecodeResult();
+ EXPECT_EQ(52, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result,
+ irsend.capture.rawlen - offset, nbits,
+ 5000, 7000, 1000, 0, 10000, true,
+ kUseDefTol, kMarkExcess, true, false));
+ EXPECT_EQ(0x12345678, result);
+
+ irsend.reset();
+ irsend.sendManchester(5000, 7000, 1000, 0, 10000, 0x87654321, nbits, 38000,
+ true, kNoRepeat, kDutyDefault, false);
+ irsend.makeDecodeResult();
+ EXPECT_EQ(54, irrecv.matchManchester(irsend.capture.rawbuf + offset, &result,
+ irsend.capture.rawlen - offset, nbits,
+ 5000, 7000, 1000, 0, 10000, true,
+ kUseDefTol, kMarkExcess, true, false));
+ EXPECT_EQ(0x87654321, result);
+}
diff --git a/lib/IRremoteESP8266-2.7.4/test/IRrecv_test.h b/lib/IRremoteESP8266-2.7.5/test/IRrecv_test.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/IRrecv_test.h
rename to lib/IRremoteESP8266-2.7.5/test/IRrecv_test.h
diff --git a/lib/IRremoteESP8266-2.7.4/test/IRsend_test.cpp b/lib/IRremoteESP8266-2.7.5/test/IRsend_test.cpp
similarity index 89%
rename from lib/IRremoteESP8266-2.7.4/test/IRsend_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/IRsend_test.cpp
index f2e280504..2f39e323d 100644
--- a/lib/IRremoteESP8266-2.7.4/test/IRsend_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/IRsend_test.cpp
@@ -786,3 +786,80 @@ TEST(TestSend, defaultBits) {
}
}
}
+
+// Tests sendManchester().
+
+// Test sending zero bits.
+TEST(TestSendManchester, SendZeroBits) {
+ IRsendTest irsend(0);
+ irsend.begin();
+ irsend.sendManchester(0, 0, 1, 0, 0, 0b1, 0);
+ EXPECT_EQ("f36000d25m0f38000d50s1m2s1", irsend.outputStr());
+ irsend.sendManchester(1, 2, 100, 3, 4, 0b1, 0);
+ EXPECT_EQ("f38000d50m1s102m200s100m3s4", irsend.outputStr());
+}
+
+// Test sending zero and one.
+TEST(TestSendManchester, SendSingleBit) {
+ IRsendTest irsend(0);
+ irsend.begin();
+ irsend.sendManchester(1000, 2000, 100, 3000, 4000, 0b0, 1);
+ EXPECT_EQ("f38000d50m1000s2100m200s200m3100s4000", irsend.outputStr());
+ irsend.sendManchester(1000, 2000, 100, 3000, 4000, 0b0, 1, 38, true,
+ kNoRepeat, kDutyDefault, false);
+ EXPECT_EQ("f38000d50m1000s2000m100s200m200s100m3000s4000",
+ irsend.outputStr());
+}
+
+// Test sending bit order.
+TEST(TestSendManchester, TestingBitSendOrder) {
+ IRsendTest irsend(0);
+ irsend.begin();
+ irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b10, 2);
+ EXPECT_EQ("f38000d50m1000s2100m200s100m100s200m3100", irsend.outputStr());
+ irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b10, 2, 38, false);
+ EXPECT_EQ("f38000d50m1000s2100m200s200m200s100m3000", irsend.outputStr());
+ irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b0001, 4, 38, true);
+ EXPECT_EQ("f38000d50m1000s2100m200s200m100s100m100s100m200s100m3000",
+ irsend.outputStr());
+ irsend.sendManchester(1000, 2000, 100, 3000, 0, 0b0001, 4, 38, false);
+ EXPECT_EQ("f38000d50m1000s2100m200s100m100s200m100s100m100s100m3100",
+ irsend.outputStr());
+}
+
+// Test sending typical data.
+TEST(TestSendManchester, SendTypicalData) {
+ IRsendTest irsend(0);
+ irsend.begin();
+ // Example from https://en.wikipedia.org/wiki/Manchester_code diagram
+ irsend.sendManchester(0, 0, 100, 0, 0, 0b10100111001, 11, 38, true);
+ EXPECT_EQ(
+ "f38000d50"
+ "m0s100m200s100"
+ "m100s200m200s200m100s100m200s100m100s100m100s200m100s100m200s100",
+ irsend.outputStr());
+ irsend.sendManchester(100, 200, 1, 300, 0, 0x1234567890ABCDEF, 64, 38, true);
+ EXPECT_EQ(
+ "f38000d50"
+ "m100s201"
+ "m2s2m1s1m1s1m2s2m1s1m2s2m1s1m1s1m2s1m1s2m2s2m1s1m1s1m2s2m2s2m2s1m1s2m1s1"
+ "m2s1m1s1m1s1m1s2m1s1m1s1m2s2m1s1m2s2m1s1m1s1m1s1m2s2m2s2m2s2m2s1m1s1m1s1"
+ "m1s2m1s1m2s1m1s2m2s1m1s1m1s1m1s2m2s1m1s1m1s1m1s1m300",
+ irsend.outputStr());
+}
+
+// Test sending more than expected bits.
+TEST(TestSendManchester, SendOverLargeData) {
+ IRsendTest irsend(0);
+ irsend.begin();
+ irsend.sendManchester(100, 200, 1, 300, 0, 0xFFFFFFFFFFFFFFFF, 70, 38, true);
+ EXPECT_EQ(
+ "f38000d50"
+ "m100s201"
+ "m2s2m1s1m1s1m1s1m1s1m1s1m2s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1"
+ "m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1"
+ "m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1"
+ "m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1m1s1"
+ "m300",
+ irsend.outputStr());
+}
diff --git a/lib/IRremoteESP8266-2.7.4/test/IRsend_test.h b/lib/IRremoteESP8266-2.7.5/test/IRsend_test.h
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/IRsend_test.h
rename to lib/IRremoteESP8266-2.7.5/test/IRsend_test.h
diff --git a/lib/IRremoteESP8266-2.7.4/test/IRutils_test.cpp b/lib/IRremoteESP8266-2.7.5/test/IRutils_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/IRutils_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/IRutils_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/Makefile b/lib/IRremoteESP8266-2.7.5/test/Makefile
similarity index 96%
rename from lib/IRremoteESP8266-2.7.4/test/Makefile
rename to lib/IRremoteESP8266-2.7.5/test/Makefile
index 7b1a4b379..dc0574a1d 100644
--- a/lib/IRremoteESP8266-2.7.4/test/Makefile
+++ b/lib/IRremoteESP8266-2.7.5/test/Makefile
@@ -39,7 +39,8 @@ TESTS = IRutils_test IRsend_test ir_NEC_test ir_GlobalCache_test \
ir_Whirlpool_test ir_Lutron_test ir_Electra_test ir_Pioneer_test \
ir_MWM_test ir_Vestel_test ir_Teco_test ir_Tcl_test ir_Lego_test IRac_test \
ir_MitsubishiHeavy_test ir_Trotec_test ir_Argo_test ir_Goodweather_test \
- ir_Inax_test ir_Neoclima_test ir_Amcor_test ir_Epson_test
+ ir_Inax_test ir_Neoclima_test ir_Amcor_test ir_Epson_test ir_Symphony_test \
+ ir_Airwell_test
# All Google Test headers. Usually you shouldn't change this
# definition.
@@ -85,7 +86,7 @@ PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.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_Teco.o ir_Tcl.o ir_Lego.o ir_Argo.o \
ir_Trotec.o ir_MitsubishiHeavy.o ir_Goodweather.o ir_Inax.o ir_Neoclima.o \
- ir_Amcor.o ir_Epson.o
+ ir_Amcor.o ir_Epson.o ir_Symphony.o ir_Airwell.o
# All the IR Protocol header files.
PROTOCOLS_H = $(USER_DIR)/ir_Amcor.h \
@@ -632,3 +633,21 @@ ir_Epson_test.o : ir_Epson_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
ir_Epson_test : $(COMMON_OBJ) ir_Epson_test.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
+
+ir_Symphony.o : $(USER_DIR)/ir_Symphony.cpp $(COMMON_DEPS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Symphony.cpp
+
+ir_Symphony_test.o : ir_Symphony_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Symphony_test.cpp
+
+ir_Symphony_test : $(COMMON_OBJ) ir_Symphony_test.o
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
+
+ir_Airwell.o : $(USER_DIR)/ir_Airwell.cpp $(COMMON_DEPS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Airwell.cpp
+
+ir_Airwell_test.o : ir_Airwell_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_Airwell_test.cpp
+
+ir_Airwell_test : $(COMMON_OBJ) ir_Airwell_test.o
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Airwell_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Airwell_test.cpp
new file mode 100644
index 000000000..b58bceced
--- /dev/null
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Airwell_test.cpp
@@ -0,0 +1,216 @@
+// Copyright 2020 David Conran
+
+#include "IRac.h"
+#include "IRrecv.h"
+#include "IRrecv_test.h"
+#include "IRsend.h"
+#include "IRsend_test.h"
+#include "gtest/gtest.h"
+
+// Tests for decodeAirwell().
+
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+// Data from:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069#issuecomment-604293514
+TEST(TestDecodeAirwell, RealExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ // ON / OFF / 25 degrees heat
+ const uint16_t rawData_1[163] = {
+ 2860, 3862,
+ 1924, 1952, 1926, 1952, 956, 984, 1924, 1028, 952, 958, 980, 956, 982,
+ 1882, 1016, 950, 1958, 1920, 1948, 1004, 954, 956, 984, 956, 952, 984,
+ 974, 966, 974, 964, 974, 1888, 1010, 960, 1948, 1002, 946, 962, 978,
+ 962, 976, 960, 948, 992, 978, 1886, 982, 984, 1924, 1954, 952, 986,
+ 3892, 3862,
+ 1924, 1954, 1924, 1954, 984, 952, 1956, 996, 954, 990, 948, 958, 980,
+ 1882, 1016, 952, 1958, 1920, 1956, 994, 944, 962, 986, 956, 972, 962,
+ 976, 962, 978, 964, 952, 1908, 1010, 960, 1948, 1002, 946, 960, 978,
+ 962, 946, 990, 978, 960, 978, 1888, 1008, 954, 1952, 1928, 982, 956,
+ 3920, 3830,
+ 1946, 1934, 1954, 1922, 976, 962, 1946, 1006, 922, 990, 948, 988, 950,
+ 1910, 1008, 964, 1922, 1952, 1924, 1030, 920, 984, 954, 986, 952, 986,
+ 952, 984, 954, 986, 952, 1910, 1010, 960, 1928, 1024, 944, 996, 924,
+ 984, 954, 988, 950, 984, 954, 1910, 1008, 960, 1920, 1958, 980, 958,
+ 4800}; // UNKNOWN 565E2BB3
+ irsend.begin();
+ irsend.reset();
+ irsend.sendRaw(rawData_1, 163, 38);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
+ ASSERT_EQ(kAirwellBits, irsend.capture.bits);
+ EXPECT_EQ(0x4F2FE7E4, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+
+ const uint16_t rawData_2[175] = {
+ 2862, 3892,
+ 1894, 1060, 890, 1944, 952, 1014, 922, 1016, 1892, 1062, 886,
+ 1020, 928, 1042, 896, 1938, 960, 1008, 920, 1020, 928, 1010, 928, 1012,
+ 1896, 1056, 892, 1016, 922, 1020, 918, 1018, 920, 1018, 920, 1946, 950,
+ 1014, 1894, 1062, 896, 1010, 928, 1010, 928, 1014, 924, 1014, 922, 1938,
+ 960, 1012, 1896, 1984, 922, 1014,
+ 3862, 3894,
+ 1892, 1062, 896, 1936, 950, 1020, 928, 1008, 1898, 1056, 892, 1016, 952,
+ 984, 954, 1910, 956, 1012, 924, 1014, 924, 1014, 922, 1014, 1892, 1060,
+ 916, 992, 926, 1010, 928, 1014, 954, 982, 944, 1918, 958, 1010, 1896,
+ 1058, 922, 986, 952, 988, 920, 1018, 950, 986, 952, 1914, 954, 1014,
+ 1892, 1986, 922, 1016,
+ 3860, 3896,
+ 1898, 1054, 924, 1908, 958, 1012, 926, 1012, 1896, 1056, 942, 966, 952,
+ 988, 950, 1910, 956, 1016, 922, 1016, 952, 988, 950, 986, 1922, 1032,
+ 916, 990, 948, 960, 988, 984, 944, 960, 978, 1918, 978, 990, 1896, 1054,
+ 924, 982, 946, 994, 954, 984, 954, 988, 950, 1910, 956, 1012, 1896, 1984,
+ 922, 1018, 4768}; // UNKNOWN 1002DCC8
+
+ irsend.begin();
+ irsend.reset();
+ irsend.sendRaw(rawData_2, 175, 38);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
+ ASSERT_EQ(kAirwellBits, irsend.capture.bits);
+ EXPECT_EQ(0x8F07E7E4, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+}
+
+TEST(TestDecodeAirwell, SyntheticExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+ irsend.reset();
+ irsend.sendAirwell(0xB0D0181B);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
+ EXPECT_EQ(kAirwellBits, irsend.capture.bits);
+ EXPECT_EQ(0xB0D0181B, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+
+ EXPECT_EQ(
+ "f38000d50"
+ "m2850s3800"
+ "m1900s950m950s1900m1900s950m950s1900m950s950m950s950m950s950"
+ "m1900s950m950s1900m1900s1900m950s950m950s950m950s950m950s950"
+ "m950s950m950s950m1900s950m950s1900m950s950m950s950m950s950"
+ "m950s950m950s950m1900s950m950s1900m1900s950m950s950"
+ "m2850s3800"
+ "m1900s950m950s1900m1900s950m950s1900m950s950m950s950m950s950"
+ "m1900s950m950s1900m1900s1900m950s950m950s950m950s950m950s950"
+ "m950s950m950s950m1900s950m950s1900m950s950m950s950m950s950"
+ "m950s950m950s950m1900s950m950s1900m1900s950m950s950"
+ "m2850s3800"
+ "m1900s950m950s1900m1900s950m950s1900m950s950m950s950m950s950"
+ "m1900s950m950s1900m1900s1900m950s950m950s950m950s950m950s950"
+ "m950s950m950s950m1900s950m950s1900m950s950m950s950m950s950"
+ "m950s950m950s950m1900s950m950s1900m1900s950m950s950"
+ "m3800s100000",
+ irsend.outputStr());
+
+ irsend.reset();
+ irsend.sendAirwell(0x4F2FE7E4);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
+ EXPECT_EQ(kAirwellBits, irsend.capture.bits);
+ EXPECT_EQ(0x4F2FE7E4, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+ EXPECT_EQ(
+ "f38000d50"
+ "m2850s3800"
+ "m1900s1900m1900s1900m950s950m1900s950m950s950m950s950m950"
+ "s1900m950s950m1900s1900m1900s950m950s950m950s950m950s950"
+ "m950s950m950s950m950s1900m950s950m1900s950m950s950m950"
+ "s950m950s950m950s950m950s1900m950s950m1900s1900m950s950"
+ "m3800s3800"
+ "m1900s1900m1900s1900m950s950m1900s950m950s950m950s950m950"
+ "s1900m950s950m1900s1900m1900s950m950s950m950s950m950s950"
+ "m950s950m950s950m950s1900m950s950m1900s950m950s950m950"
+ "s950m950s950m950s950m950s1900m950s950m1900s1900m950s950"
+ "m3800s3800"
+ "m1900s1900m1900s1900m950s950m1900s950m950s950m950s950m950"
+ "s1900m950s950m1900s1900m1900s950m950s950m950s950m950s950"
+ "m950s950m950s950m950s1900m950s950m1900s950m950s950m950"
+ "s950m950s950m950s950m950s1900m950s950m1900s1900m950s950"
+ "m4750s100000",
+ irsend.outputStr());
+
+ irsend.reset();
+ irsend.sendAirwell(0x70F8181B);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
+ EXPECT_EQ(kAirwellBits, irsend.capture.bits);
+ EXPECT_EQ(0x70F8181B, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+}
+
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1069
+// Data from:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1069#issuecomment-607659677
+TEST(TestDecodeAirwell, RealExample2) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ // "When I change from 22° to 23° :"
+ const uint16_t rawData[175] = {
+ 2890, 2918,
+ 924, 1006, 946, 1886, 1986, 1922, 978, 958, 1952, 1000, 952, 956, 974,
+ 964, 976, 1884, 1016, 952, 1948, 1006, 944, 962, 980, 958, 982, 958, 952,
+ 982, 978, 960, 980, 956, 986, 956, 974, 1888, 1014, 954, 1948, 1002, 948,
+ 960, 980, 960, 950, 986, 1006, 962, 980, 1854, 1036, 932, 1948, 1928, 984,
+ 954,
+ 3918, 2920,
+ 922, 1008, 942, 1888, 1984, 1926, 984, 950, 1952, 1000, 952, 956, 984,
+ 956, 954, 1908, 1014, 952, 1948, 1002, 948, 960, 950, 986, 984, 956, 954,
+ 984, 956, 984, 946, 992, 948, 992, 948, 1910, 1012, 958, 1954, 996, 922,
+ 984, 956, 986, 956, 980, 950, 988, 954, 1910, 1010, 956, 1946, 1932, 978,
+ 962,
+ 3922, 2914,
+ 918, 1010, 920, 1912, 1980, 1928, 982, 956, 1944, 1006, 924, 982, 958,
+ 982, 948, 1912, 1008, 958, 1952, 1000, 920, 988, 952, 982, 958, 984, 958,
+ 978, 952, 986, 986, 952, 958, 984, 946, 1912, 1010, 962, 1948, 1004, 926,
+ 980, 950, 988, 952, 984, 956, 982, 948, 1916, 1016, 952, 1950, 1926, 984,
+ 952, 4830}; // UNKNOWN 8E34167B
+ irsend.begin();
+ irsend.reset();
+ irsend.sendRaw(rawData, 175, 38);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
+ ASSERT_EQ(kAirwellBits, irsend.capture.bits);
+ EXPECT_EQ(0xB0C0181B, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+
+ // Resend it as a synthetic to see if it decodes to the same value.
+ irsend.reset();
+ irsend.sendAirwell(0xB0C0181B);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::AIRWELL, irsend.capture.decode_type);
+ ASSERT_EQ(kAirwellBits, irsend.capture.bits);
+ EXPECT_EQ(0xB0C0181B, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+}
+
+TEST(TestUtils, Housekeeping) {
+ ASSERT_EQ("AIRWELL", typeToString(decode_type_t::AIRWELL));
+ ASSERT_EQ(decode_type_t::AIRWELL, strToDecodeType("AIRWELL"));
+ ASSERT_FALSE(hasACState(decode_type_t::AIRWELL));
+ ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::AIRWELL));
+ ASSERT_EQ(kAirwellBits, IRsend::defaultBits(decode_type_t::AIRWELL));
+ ASSERT_EQ(kAirwellMinRepeats, IRsend::minRepeats(decode_type_t::AIRWELL));
+}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Aiwa_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Aiwa_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Aiwa_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Aiwa_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Amcor_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Amcor_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Amcor_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Amcor_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Argo_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Argo_test.cpp
similarity index 95%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Argo_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Argo_test.cpp
index d5a5d17ad..3ab890adc 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Argo_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Argo_test.cpp
@@ -1,5 +1,6 @@
// Copyright 2019 David Conran
#include "ir_Argo.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -105,6 +106,12 @@ TEST(TestDecodeArgo, SyntheticDecode) {
EXPECT_EQ(decode_type_t::ARGO, irsend.capture.decode_type);
EXPECT_EQ(kArgoBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
+ EXPECT_EQ(
+ "Power: On, Mode: 0 (Cool), Fan: 0 (Auto), Temp: 20C, Room Temp: 21C, "
+ "Max: On, IFeel: On, Night: On",
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Carrier_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Carrier_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Carrier_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Carrier_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Coolix_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Coolix_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Coolix_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Coolix_test.cpp
index 20a46c7b4..45d53a12f 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Coolix_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Coolix_test.cpp
@@ -773,6 +773,8 @@ TEST(TestCoolixACClass, Issue985) {
EXPECT_EQ(kCoolixBits, ac._irsend.capture.bits);
EXPECT_EQ(kCoolixOff, ac._irsend.capture.value);
EXPECT_EQ("Power: Off", IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
@@ -793,6 +795,7 @@ TEST(TestCoolixACClass, Issue985) {
EXPECT_EQ(
"Power: On, Mode: 0 (Cool), Fan: 5 (Auto), Temp: 20C, Zone Follow: Off, "
"Sensor Temp: Off", IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac._irsend.reset();
@@ -808,6 +811,7 @@ TEST(TestCoolixACClass, Issue985) {
EXPECT_EQ(kCoolixBits, ac._irsend.capture.bits);
EXPECT_EQ(kCoolixOff, ac._irsend.capture.value);
EXPECT_EQ("Power: Off", IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestCoolixACClass, PowerStateWithSetRaw) {
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Daikin_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Daikin_test.cpp
similarity index 92%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Daikin_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Daikin_test.cpp
index 60d39d9a3..e37c6b00a 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Daikin_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Daikin_test.cpp
@@ -1545,6 +1545,11 @@ TEST(TestUtils, Housekeeping) {
ASSERT_EQ(decode_type_t::DAIKIN216, strToDecodeType("DAIKIN216"));
ASSERT_TRUE(hasACState(decode_type_t::DAIKIN216));
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::DAIKIN216));
+
+ ASSERT_EQ("DAIKIN64", typeToString(decode_type_t::DAIKIN64));
+ ASSERT_EQ(decode_type_t::DAIKIN64, strToDecodeType("DAIKIN64"));
+ ASSERT_FALSE(hasACState(decode_type_t::DAIKIN64));
+ ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::DAIKIN64));
}
// https://github.com/crankyoldgit/IRremoteESP8266/issues/582#issuecomment-453863879
@@ -2581,6 +2586,8 @@ TEST(TestDecodeDaikin128, RealExample) {
"On Timer: Off, On Timer: 07:30, Off Timer: Off, Off Timer: 22:00, "
"Light Toggle: 0 (Off)",
IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t result, prev;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827
@@ -2971,6 +2978,8 @@ TEST(TestDecodeDaikin152, RealExample) {
"Power: Off, Mode: 0 (Auto), Temp: 26C, Fan: 2 (UNKNOWN), Swing(V): Off, "
"Powerful: Off, Quiet: On, Econo: Off, Sensor: Off, Comfort: Off",
IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t result, prev;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
// https://github.com/crankyoldgit/IRremoteESP8266/issues/873
@@ -3006,6 +3015,8 @@ TEST(TestDecodeDaikin152, SyntheticExample) {
"Power: On, Mode: 3 (Cool), Temp: 20C, Fan: 1 (Low), Swing(V): On, "
"Powerful: Off, Quiet: Off, Econo: Off, Sensor: Off, Comfort: Off",
IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t result, prev;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
}
TEST(TestDaikin2ClassNew, Issue908) {
@@ -3400,3 +3411,282 @@ TEST(TestDaikin2Class, Issue1035) {
ac.toString());
ASSERT_FALSE(ac.toCommon().power);
}
+
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1064
+// Data from:
+// https://docs.google.com/spreadsheets/d/1sxjLQCRLMFM1FQpttBXsye2JG5hHIe2BrKnKDuPV9Bw/edit#gid=726071135&range=A1
+TEST(TestDecodeDaikin64, RealExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ uint16_t rawData[137] = {
+ 9864, 9778, 9810, 9728, 4666, 2482, 384, 342, 390, 922, 386, 928, 388,
+ 348, 388, 920, 386, 348, 390, 342, 384, 330, 414, 342, 390, 922, 386, 348,
+ 390, 342, 382, 352, 384, 352, 382, 924, 386, 356, 382, 344, 384, 350, 388,
+ 346, 390, 342, 386, 348, 386, 928, 388, 348, 388, 354, 388, 888, 412, 928,
+ 390, 896, 416, 348, 386, 348, 388, 346, 388, 342, 384, 358, 388, 340, 384,
+ 926, 384, 932, 386, 346, 388, 922, 384, 350, 384, 348, 384, 358, 382, 338,
+ 394, 922, 388, 928, 386, 350, 384, 926, 390, 344, 388, 342, 386, 356, 388,
+ 338, 382, 928, 382, 932, 390, 344, 386, 924, 390, 344, 388, 314, 414, 356,
+ 384, 344, 386, 346, 390, 926, 386, 924, 388, 924, 388, 926, 386, 924, 388,
+ 350, 388, 20258, 4670};
+
+ irsend.begin();
+ irsend.reset();
+ irsend.sendRaw(rawData, 137, kDaikin64Freq);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::DAIKIN64, irsend.capture.decode_type);
+ ASSERT_EQ(kDaikin64Bits, irsend.capture.bits);
+ EXPECT_EQ(0x7C16161607204216, irsend.capture.value);
+ EXPECT_EQ(
+ "Power Toggle: On, Mode: 2 (Cool), Temp: 16C, Fan: 4 (Medium), "
+ "Turbo: Off, Quiet: Off, Swing(V): Off, Sleep: Off, "
+ "Clock: 07:20, On Timer: Off, Off Timer: Off",
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t result, prev;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
+}
+
+TEST(TestDecodeDaikin64, SyntheticExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+
+ irsend.begin();
+ irsend.reset();
+ irsend.sendDaikin64(0x7C16161607204216);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::DAIKIN64, irsend.capture.decode_type);
+ ASSERT_EQ(kDaikin64Bits, irsend.capture.bits);
+ EXPECT_EQ(0x7C16161607204216, irsend.capture.value);
+}
+
+TEST(TestDaikin64Class, ChecksumAndSetGetRaw) {
+ IRDaikin64 ac(kGpioUnused);
+
+ const uint64_t valid = 0x7C16161607204216;
+ const uint64_t invalid = 0x1C16161607204216;
+ ASSERT_NE(valid, invalid);
+ ASSERT_EQ(0x07, IRDaikin64::calcChecksum(valid));
+ ASSERT_TRUE(IRDaikin64::validChecksum(valid));
+ ASSERT_FALSE(IRDaikin64::validChecksum(invalid));
+ ac.setRaw(valid);
+ ASSERT_EQ(valid, ac.getRaw());
+ ac.setRaw(invalid);
+ ASSERT_EQ(valid, ac.getRaw());
+}
+
+TEST(TestDaikin64Class, Temperature) {
+ IRDaikin64 ac(0);
+ ac.begin();
+ ac.setTemp(0);
+ EXPECT_EQ(kDaikin64MinTemp, ac.getTemp());
+
+ ac.setTemp(255);
+ EXPECT_EQ(kDaikin64MaxTemp, ac.getTemp());
+
+ ac.setTemp(kDaikin64MinTemp);
+ EXPECT_EQ(kDaikin64MinTemp, ac.getTemp());
+
+ ac.setTemp(kDaikin64MaxTemp);
+ EXPECT_EQ(kDaikin64MaxTemp, ac.getTemp());
+
+ ac.setTemp(kDaikin64MinTemp - 1);
+ EXPECT_EQ(kDaikin64MinTemp, ac.getTemp());
+
+ ac.setTemp(kDaikin64MaxTemp + 1);
+ EXPECT_EQ(kDaikin64MaxTemp, ac.getTemp());
+
+ ac.setTemp(kDaikin64MinTemp + 1);
+ EXPECT_EQ(kDaikin64MinTemp + 1, ac.getTemp());
+
+ ac.setTemp(21);
+ EXPECT_EQ(21, ac.getTemp());
+
+ ac.setTemp(25);
+ EXPECT_EQ(25, ac.getTemp());
+
+ ac.setTemp(29);
+ EXPECT_EQ(29, ac.getTemp());
+
+ // Ref: https://docs.google.com/spreadsheets/d/1sxjLQCRLMFM1FQpttBXsye2JG5hHIe2BrKnKDuPV9Bw/edit#gid=1521758824&range=R2:AG2
+ const uint64_t deg16 = 0x8C16105500001216;
+ ac.setRaw(deg16);
+ EXPECT_EQ(16, ac.getTemp());
+}
+
+TEST(TestDaikin64Class, OperatingMode) {
+ IRDaikin64 ac(0);
+ ac.begin();
+
+ ac.setMode(kDaikin64Cool);
+ EXPECT_EQ(kDaikin64Cool, ac.getMode());
+
+ ac.setMode(kDaikin64Fan);
+ EXPECT_EQ(kDaikin64Fan, ac.getMode());
+
+ ac.setMode(kDaikin64Dry);
+ EXPECT_EQ(kDaikin64Dry, ac.getMode());
+
+ ac.setMode(kDaikin64Fan + 1);
+ EXPECT_EQ(kDaikin64Cool, ac.getMode());
+
+ ac.setMode(255);
+ EXPECT_EQ(kDaikin64Cool, ac.getMode());
+
+ // Ref: https://docs.google.com/spreadsheets/d/1sxjLQCRLMFM1FQpttBXsye2JG5hHIe2BrKnKDuPV9Bw/edit#gid=1521758824&range=R2:AG2
+ const uint64_t cool = 0x8C16105500001216;
+ ac.setMode(kDaikin64Dry);
+ ac.setRaw(cool);
+ EXPECT_EQ(kDaikin64Cool, ac.getMode());
+}
+
+TEST(TestDaikin64Class, PowerToggle) {
+ IRDaikin64 ac(0);
+ ac.begin();
+
+ ac.setPowerToggle(true);
+ EXPECT_TRUE(ac.getPowerToggle());
+ ac.setPowerToggle(false);
+ EXPECT_FALSE(ac.getPowerToggle());
+ ac.setPowerToggle(true);
+ EXPECT_TRUE(ac.getPowerToggle());
+}
+
+TEST(TestDaikin64Class, FanSpeed) {
+ IRDaikin64 ac(kGpioUnused);
+ ac.begin();
+
+ // Unexpected value should default to Auto.
+ ac.setFan(0);
+ EXPECT_EQ(kDaikin64FanAuto, ac.getFan());
+ ac.setFan(255);
+ EXPECT_EQ(kDaikin64FanAuto, ac.getFan());
+ ac.setFan(5);
+ EXPECT_EQ(kDaikin64FanAuto, ac.getFan());
+
+ ac.setFan(kDaikin64FanHigh);
+ EXPECT_EQ(kDaikin64FanHigh, ac.getFan());
+
+ // Beyond Quiet should default to Auto.
+ ac.setFan(kDaikin64FanQuiet + 1);
+ EXPECT_EQ(kDaikin64FanAuto, ac.getFan());
+
+ ac.setFan(kDaikin64FanMed);
+ EXPECT_EQ(kDaikin64FanMed, ac.getFan());
+
+ ac.setFan(kDaikin64FanLow);
+ EXPECT_EQ(kDaikin64FanLow, ac.getFan());
+
+ ac.setFan(kDaikin64FanTurbo);
+ EXPECT_EQ(kDaikin64FanTurbo, ac.getFan());
+
+ ac.setFan(kDaikin64FanAuto);
+ EXPECT_EQ(kDaikin64FanAuto, ac.getFan());
+
+ ac.setFan(kDaikin64FanQuiet);
+ EXPECT_EQ(kDaikin64FanQuiet, ac.getFan());
+}
+
+TEST(TestDaikin64Class, Turbo) {
+ IRDaikin64 ac(kGpioUnused);
+ ac.begin();
+ ac.setFan(kDaikin64FanAuto);
+ ac.setTurbo(true);
+ EXPECT_TRUE(ac.getTurbo());
+ EXPECT_EQ(kDaikin64FanTurbo, ac.getFan());
+ ac.setTurbo(false);
+ EXPECT_NE(kDaikin64FanTurbo, ac.getFan());
+ EXPECT_FALSE(ac.getTurbo());
+ ac.setTurbo(true);
+ EXPECT_TRUE(ac.getTurbo());
+}
+
+TEST(TestDaikin64Class, Quiet) {
+ IRDaikin64 ac(kGpioUnused);
+ ac.begin();
+ ac.setFan(kDaikin64FanAuto);
+ ac.setQuiet(true);
+ EXPECT_TRUE(ac.getQuiet());
+ EXPECT_EQ(kDaikin64FanQuiet, ac.getFan());
+ ac.setQuiet(false);
+ EXPECT_NE(kDaikin64FanQuiet, ac.getFan());
+ EXPECT_FALSE(ac.getQuiet());
+ ac.setQuiet(true);
+ EXPECT_TRUE(ac.getQuiet());
+}
+
+TEST(TestDaikin64Class, Sleep) {
+ IRDaikin64 ac(kGpioUnused);
+ ac.begin();
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+ ac.setSleep(false);
+ EXPECT_FALSE(ac.getSleep());
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+}
+
+TEST(TestDaikin64Class, SwingVertical) {
+ IRDaikin64 ac(kGpioUnused);
+ ac.begin();
+ ac.setSwingVertical(true);
+ EXPECT_TRUE(ac.getSwingVertical());
+ ac.setSwingVertical(false);
+ EXPECT_FALSE(ac.getSwingVertical());
+ ac.setSwingVertical(true);
+ EXPECT_TRUE(ac.getSwingVertical());
+}
+
+TEST(TestDaikin64Class, Clock) {
+ IRDaikin64 ac(kGpioUnused);
+ ac.begin();
+
+ ac.setClock(0);
+ EXPECT_EQ(0, ac.getClock());
+ ac.setClock(23 * 60 + 59);
+ EXPECT_EQ(23 * 60 + 59, ac.getClock());
+ ac.setClock(23 * 60 + 59 + 1);
+ EXPECT_EQ(0, ac.getClock());
+ ac.setClock(24 * 60 + 99);
+ EXPECT_EQ(0, ac.getClock());
+}
+
+// Test human readable output.
+TEST(TestDaikin64Class, HumanReadable) {
+ IRDaikin64 ac(kGpioUnused);
+ EXPECT_EQ(
+ "Power Toggle: On, Mode: 2 (Cool), Temp: 16C, Fan: 4 (Medium), "
+ "Turbo: Off, Quiet: Off, Swing(V): Off, Sleep: Off, "
+ "Clock: 07:20, On Timer: Off, Off Timer: Off",
+ ac.toString());
+ ac.setPowerToggle(false);
+ ac.setMode(kDaikin64Fan);
+ ac.setTemp(30);
+ ac.setFan(kDaikin64FanAuto);
+ ac.setSwingVertical(true);
+ EXPECT_EQ(
+ "Power Toggle: Off, Mode: 4 (Fan), Temp: 30C, Fan: 1 (Auto), "
+ "Turbo: Off, Quiet: Off, Swing(V): On, Sleep: Off, "
+ "Clock: 07:20, On Timer: Off, Off Timer: Off",
+ ac.toString());
+ ac.setTurbo(true);
+ ac.setOffTimeEnabled(true);
+ ac.setOffTime(23 * 60 + 30);
+ EXPECT_EQ(
+ "Power Toggle: Off, Mode: 4 (Fan), Temp: 30C, Fan: 3 (Turbo), "
+ "Turbo: On, Quiet: Off, Swing(V): On, Sleep: Off, "
+ "Clock: 07:20, On Timer: Off, Off Timer: 23:30",
+ ac.toString());
+ ac.setQuiet(true);
+ ac.setSleep(true);
+ ac.setClock(12 * 60 + 31);
+ ac.setOnTimeEnabled(true);
+ ac.setOnTime(8 * 60 + 59);
+ ac.setOffTimeEnabled(false);
+ EXPECT_EQ(
+ "Power Toggle: Off, Mode: 4 (Fan), Temp: 30C, Fan: 9 (Quiet), "
+ "Turbo: Off, Quiet: On, Swing(V): On, Sleep: On, "
+ "Clock: 12:31, On Timer: 08:30, Off Timer: Off",
+ ac.toString());
+}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Denon_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Denon_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Denon_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Denon_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Dish_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Dish_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Dish_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Dish_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Electra_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Electra_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Electra_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Electra_test.cpp
index b49482433..1fddf537b 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Electra_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Electra_test.cpp
@@ -103,6 +103,8 @@ TEST(TestDecodeElectraAC, RealExampleDecode) {
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
"Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off",
IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestIRElectraAcClass, Power) {
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Epson_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Epson_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Epson_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Epson_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Fujitsu_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Fujitsu_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Fujitsu_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Fujitsu_test.cpp
index 2aead1e13..aa8d2d941 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Fujitsu_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Fujitsu_test.cpp
@@ -1,5 +1,5 @@
// Copyright 2017 Jonny Graham, David Conran
-
+#include "IRac.h"
#include "IRrecv_test.h"
#include "IRsend.h"
#include "IRsend_test.h"
@@ -316,6 +316,12 @@ TEST(TestDecodeFujitsuAC, SyntheticShortMessages) {
ASSERT_EQ(kFujitsuAcMinBits + 8, irsend.capture.bits);
uint8_t expected_arrah2e[7] = {0x14, 0x63, 0x0, 0x10, 0x10, 0x02, 0xFD};
EXPECT_STATE_EQ(expected_arrah2e, irsend.capture.state, irsend.capture.bits);
+ EXPECT_EQ(
+ "Model: 1 (ARRAH2E), Power: Off, Mode: 0 (Auto), Temp: 16C, "
+ "Fan: 0 (Auto), Clean: Off, Filter: Off, Swing: 0 (Off), Command: N/A",
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
irsend.reset();
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_GICable_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_GICable_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_GICable_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_GICable_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_GlobalCache_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_GlobalCache_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_GlobalCache_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_GlobalCache_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Goodweather_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Goodweather_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Goodweather_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Goodweather_test.cpp
index 6345d2398..be07b9d09 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Goodweather_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Goodweather_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2019 David Conran
#include "ir_Goodweather.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -276,11 +277,12 @@ uint16_t rawData_FAD2BE31[197] = {
EXPECT_EQ(0x0, irsend.capture.address);
EXPECT_EQ(0x0, irsend.capture.command);
EXPECT_FALSE(irsend.capture.repeat);
- ac.setRaw(irsend.capture.value);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 22C, Fan: 3 (Low), Turbo: -, Light: -, "
"Sleep: -, Swing: 1 (Slow), Command: 4 (Swing)",
- ac.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Gree_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Gree_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Gree_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Gree_test.cpp
index 6c8672c77..a824cd10a 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Gree_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Gree_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 David Conran
#include "ir_Gree.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRremoteESP8266.h"
@@ -576,7 +577,9 @@ TEST(TestDecodeGree, NormalRealExample) {
"Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 26C, Fan: 1 (Low), "
"Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, "
"Swing(V) Mode: Manual, Swing(V): 2 (UNKNOWN), Timer: Off",
- irgree.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestGreeClass, toCommon) {
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Haier_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Haier_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Haier_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Haier_test.cpp
index ee55d2866..cdd2894df 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Haier_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Haier_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2018 David Conran
#include "ir_Haier.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -818,13 +819,13 @@ TEST(TestDecodeHaierAC, RealExample1) {
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
- IRHaierAC haier(0);
- haier.setRaw(irsend.capture.state);
EXPECT_EQ(
"Command: 1 (On), Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), "
"Swing: 0 (Off), Sleep: Off, Health: Off, "
"Clock: 00:01, On Timer: Off, Off Timer: Off",
- haier.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Decode a "real" example message.
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Hitachi_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Hitachi_test.cpp
similarity index 65%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Hitachi_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Hitachi_test.cpp
index 1f04ee8ee..aef8008ff 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Hitachi_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Hitachi_test.cpp
@@ -572,6 +572,12 @@ TEST(TestDecodeHitachiAC1, NormalRealExample) {
EXPECT_EQ(HITACHI_AC1, irsend.capture.decode_type);
ASSERT_EQ(kHitachiAc1Bits, irsend.capture.bits);
EXPECT_STATE_EQ(hitachi_code, irsend.capture.state, kHitachiAc1Bits);
+ EXPECT_EQ(
+ "Model: 2 (R-LT0541-HTA-B), Power: Off, Power Toggle: On, "
+ "Mode: 6 (Cool), Temp: 23C, Fan: 1 (Auto), "
+ "Swing(V) Toggle: Off, Swing(V): Off, Swing(H): Off, Sleep: Off, "
+ "On Timer: Off, Off Timer: Off",
+ IRAcUtils::resultAcToString(&irsend.capture));
}
// Tests for sendHitachiAC2().
@@ -809,13 +815,18 @@ TEST(TestUtils, Housekeeping) {
ASSERT_EQ("HITACHI_AC1", typeToString(decode_type_t::HITACHI_AC1));
ASSERT_EQ(decode_type_t::HITACHI_AC1, strToDecodeType("HITACHI_AC1"));
ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC1));
- ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC1));
+ ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC1));
ASSERT_EQ("HITACHI_AC2", typeToString(decode_type_t::HITACHI_AC2));
ASSERT_EQ(decode_type_t::HITACHI_AC2, strToDecodeType("HITACHI_AC2"));
ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC2));
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC2));
+ ASSERT_EQ("HITACHI_AC3", typeToString(decode_type_t::HITACHI_AC3));
+ ASSERT_EQ(decode_type_t::HITACHI_AC3, strToDecodeType("HITACHI_AC3"));
+ ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC3));
+ ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::HITACHI_AC3));
+
ASSERT_EQ("HITACHI_AC424", typeToString(decode_type_t::HITACHI_AC424));
ASSERT_EQ(decode_type_t::HITACHI_AC424, strToDecodeType("HITACHI_AC424"));
ASSERT_TRUE(hasACState(decode_type_t::HITACHI_AC424));
@@ -915,6 +926,8 @@ TEST(TestDecodeHitachiAc424, RealExample) {
"Power: On, Mode: 3 (Cool), Temp: 23C, Fan: 5 (Auto), "
"Swing(V) Toggle: Off, Button: 19 (Power/Mode)",
IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestDecodeHitachiAc424, SyntheticExample) {
@@ -1113,7 +1126,7 @@ TEST(TestIRHitachiAc424Class, HumanReadable) {
}
TEST(TestIRHitachiAc424Class, toCommon) {
- IRHitachiAc424 ac(0);
+ IRHitachiAc424 ac(kGpioUnused);
ac.setPower(true);
ac.setMode(kHitachiAc424Cool);
ac.setTemp(20);
@@ -1139,3 +1152,652 @@ TEST(TestIRHitachiAc424Class, toCommon) {
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
+
+TEST(TestDecodeHitachiAc3, SyntheticExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ uint8_t expected[kHitachiAc3StateLength - 4] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE6, 0x19, 0x89, 0x76, 0x01,
+ 0xFE, 0x3F, 0xC0, 0x2F, 0xD0, 0x18, 0xE7, 0x00, 0xFF, 0xA0, 0x5F};
+
+ irsend.reset();
+ irsend.sendHitachiAc3(expected, kHitachiAc3StateLength - 4);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(kHitachiAc3Bits - 32, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
+}
+
+// Decode a 'real' HitachiAc3 message.
+TEST(TestDecodeHitachiAc3, RealExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ uint8_t expected[kHitachiAc3StateLength - 4] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE6, 0x19, 0x89, 0x76, 0x01,
+ 0xFE, 0x3F, 0xC0, 0x2F, 0xD0, 0x18, 0xE7, 0x00, 0xFF, 0xA0, 0x5F};
+
+ // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1060#issuecomment-597519432
+ uint16_t rawData[371] = {
+ // Power Off
+ 3422, 1660, 464, 1264, 438, 426, 438, 402, 486, 426, 440, 402, 462, 402,
+ 488, 428, 438, 402, 460, 404, 488, 426, 440, 424, 436, 428, 462, 1240,
+ 466, 398, 462, 404, 486, 426, 438, 402, 464, 400, 490, 400, 464, 426, 438,
+ 402, 488, 428, 436, 428, 462, 376, 486, 404, 474, 416, 438, 400, 488, 402,
+ 462, 426, 438, 426, 458, 1246, 464, 426, 436, 1244, 488, 1266, 434, 1268,
+ 436, 1242, 486, 1242, 462, 1240, 464, 426, 462, 1266, 438, 1242, 462,
+ 1240, 514, 1214, 466, 1236, 462, 1266, 464, 1264, 438, 1266, 438, 1240,
+ 488, 400, 466, 424, 440, 402, 486, 404, 462, 402, 464, 402, 488, 426, 438,
+ 402, 462, 402, 488, 1264, 438, 1242, 460, 428, 462, 428, 436, 1264, 440,
+ 1240, 488, 1240, 464, 1240, 460, 402, 490, 424, 440, 1264, 438, 1242, 512,
+ 402, 438, 426, 466, 398, 464, 1266, 440, 400, 462, 402, 488, 1264, 438,
+ 402, 462, 402, 482, 432, 438, 1264, 436, 404, 488, 1240, 462, 1264, 438,
+ 402, 486, 1246, 456, 1266, 438, 1238, 488, 402, 462, 1240, 462, 402, 512,
+ 402, 438, 428, 438, 426, 462, 430, 434, 428, 438, 402, 512, 376, 462,
+ 1240, 464, 1264, 458, 1270, 436, 1242, 462, 1240, 486, 1242, 460, 1242,
+ 462, 1242, 486, 1240, 464, 1240, 464, 1238, 492, 1264, 436, 1266, 440,
+ 400, 488, 426, 436, 430, 434, 430, 460, 404, 462, 426, 438, 402, 488, 426,
+ 436, 1264, 466, 1238, 462, 1242, 462, 1266, 438, 1238, 490, 1264, 438,
+ 426, 438, 1240, 486, 406, 462, 402, 462, 400, 488, 428, 436, 426, 438,
+ 402, 484, 1268, 438, 426, 436, 1242, 488, 1266, 436, 402, 462, 402, 502,
+ 386, 464, 1240, 464, 1240, 488, 426, 438, 426, 438, 402, 488, 1240, 462,
+ 1266, 438, 1242, 486, 428, 440, 424, 438, 1266, 460, 1268, 438, 1264, 438,
+ 404, 486, 428, 438, 426, 438, 402, 490, 400, 462, 426, 436, 402, 490, 426,
+ 438, 1240, 462, 1268, 460, 1268, 434, 1266, 436, 1240, 514, 1238, 438,
+ 1240, 488, 1240, 460, 406, 464, 426, 436, 402, 488, 402, 462, 402, 462,
+ 1264, 462, 404, 462, 1266, 434, 1268, 464, 1264, 438, 1242, 464, 1238,
+ 488, 1266, 438, 402, 462, 1268, 458, 430, 410};
+
+ irsend.reset();
+ irsend.sendRaw(rawData, 371, kHitachiAcFreq);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(kHitachiAc3Bits - 32, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
+}
+
+TEST(TestDecodeHitachiAc3, SyntheticTempChangeExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ const uint16_t expectedLength = kHitachiAc3MinStateLength + 2;
+ uint8_t expected[expectedLength] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE3, 0x1C, 0x89, 0x76, 0x08,
+ 0xF7, 0x3F, 0xC0, 0x15, 0xEA};
+
+ irsend.reset();
+ irsend.sendHitachiAc3(expected, expectedLength);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(expectedLength * 8, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
+}
+
+// Decode a 'real' Temp Change HitachiAc3 message.
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1060#issuecomment-597592537
+TEST(TestDecodeHitachiAc3, RealTempChangeExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ const uint8_t expected[kHitachiAc3MinStateLength + 2] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE3, 0x1C, 0x89, 0x76, 0x08,
+ 0xF7, 0x3F, 0xC0, 0x15, 0xEA};
+ const uint16_t expectedBits = kHitachiAc3MinBits + 2 * 8;
+
+ const uint16_t rawData[275] = {
+ // Change Temp
+ 3422, 1636, 490, 1242, 484, 380, 488, 400, 466, 426, 432, 406, 490, 400,
+ 464, 426, 462, 398, 466, 376, 492, 400, 458, 404, 490, 400, 466, 1262,
+ 434, 430, 464, 400, 490, 400, 458, 380, 490, 374, 490, 426, 432, 430, 464,
+ 400, 464, 426, 460, 402, 468, 372, 490, 400, 460, 404, 490, 374, 490, 400,
+ 484, 378, 490, 398, 464, 1240, 490, 398, 466, 1238, 464, 1266, 434, 1268,
+ 466, 1238, 466, 1240, 484, 1218, 490, 400, 460, 1246, 484, 1242, 466,
+ 1214, 488, 1240, 486, 1218, 490, 1214, 488, 1266, 434, 1242, 490, 1214,
+ 490, 424, 460, 404, 464, 374, 492, 424, 434, 430, 466, 400, 464, 426, 464,
+ 376, 492, 1236, 464, 1240, 488, 402, 466, 374, 490, 400, 458, 1244, 490,
+ 1238, 496, 1234, 436, 404, 488, 400, 464, 1240, 484, 1244, 464, 1238, 466,
+ 426, 434, 430, 466, 400, 464, 1264, 434, 406, 490, 374, 490, 1264, 458,
+ 404, 466, 400, 466, 424, 466, 1238, 464, 400, 466, 1238, 486, 1216, 490,
+ 400, 464, 1240, 486, 1240, 466, 1238, 460, 432, 432, 430, 468, 374, 488,
+ 426, 462, 1242, 464, 400, 466, 426, 434, 404, 490, 374, 490, 1240, 484,
+ 1244, 466, 1240, 462, 428, 436, 1242, 490, 1212, 490, 1264, 466, 1236,
+ 466, 1214, 490, 1240, 488, 1240, 466, 1236, 466, 1264, 434, 1268, 464,
+ 400, 494, 400, 430, 406, 488, 376, 488, 428, 432, 432, 462, 402, 462, 426,
+ 458, 1220, 488, 1214, 490, 1240, 484, 406, 466, 1212, 490, 426, 462, 1216,
+ 488, 400, 464, 402, 488, 402, 462, 374, 492, 1262, 460, 380, 488, 1240,
+ 464, 428, 462, 1214, 492, 1236, 462, 1216, 490};
+
+ irsend.reset();
+ irsend.sendRaw(rawData, 275, kHitachiAcFreq);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(expectedBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, expectedBits);
+}
+
+// Decode a 'real' Cancel Timer HitachiAc3 message.
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1060#issuecomment-598631576
+TEST(TestDecodeHitachiAc3, RealCancelTimerExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ const uint8_t expected[kHitachiAc3MinStateLength] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE2, 0x1D, 0x89, 0x76, 0x0D,
+ 0xF2, 0x3F, 0xC0};
+ const uint16_t expectedBits = kHitachiAc3MinBits;
+
+ const uint16_t rawData[243] = {
+ // Cancel Timer
+ 3368, 1688, 460, 1244, 456, 434, 458, 406, 456, 408, 480, 410, 458, 406,
+ 458, 406, 484, 406, 458, 406, 458, 432, 428, 464, 456, 380, 458, 1242,
+ 458, 432, 456, 406, 486, 378, 430, 458, 456, 408, 458, 406, 456, 434, 456,
+ 410, 454, 408, 454, 434, 460, 404, 458, 406, 454, 436, 456, 408, 458, 406,
+ 458, 432, 456, 434, 430, 1246, 484, 404, 484, 1218, 458, 1244, 484, 1244,
+ 460, 1244, 456, 1270, 430, 1274, 460, 404, 484, 1218, 486, 1244, 456,
+ 1244, 456, 1248, 454, 1272, 460, 1268, 432, 1246, 484, 1244, 458, 1244,
+ 462, 404, 456, 434, 458, 432, 432, 408, 456, 434, 460, 404, 460, 404, 484,
+ 406, 432, 432, 458, 1298, 402, 432, 460, 404, 460, 404, 482, 1244, 460,
+ 1270, 462, 1214, 456, 1272, 460, 404, 456, 1246, 486, 1244, 458, 1244,
+ 458, 406, 454, 460, 434, 404, 460, 1268, 430, 460, 432, 406, 458, 1244,
+ 456, 434, 458, 406, 456, 432, 460, 1268, 432, 406, 458, 1244, 484, 1272,
+ 432, 430, 432, 1298, 378, 1298, 458, 1244, 484, 406, 460, 1242, 458, 406,
+ 458, 1246, 456, 1272, 458, 406, 458, 432, 458, 404, 460, 404, 456, 408,
+ 484, 1272, 432, 432, 432, 406, 454, 1272, 458, 1246, 458, 1244, 484, 1268,
+ 436, 1242, 458, 1298, 402, 1274, 456, 1244, 458, 1244, 486, 1242, 458,
+ 408, 486, 378, 454, 460, 434, 406, 458, 406, 484, 406, 458, 406, 458, 408,
+ 452, 1302, 434, 1244, 430};
+
+ irsend.reset();
+ irsend.sendRaw(rawData, 243, kHitachiAcFreq);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(expectedBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, expectedBits);
+}
+
+TEST(TestDecodeHitachiAc3, SyntheticCancelTimerExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ const uint8_t expected[kHitachiAc3MinStateLength] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE2, 0x1D, 0x89, 0x76, 0x0D,
+ 0xF2, 0x3F, 0xC0};
+
+ irsend.reset();
+ irsend.sendHitachiAc3(expected, kHitachiAc3MinStateLength);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(kHitachiAc3MinBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
+}
+
+// Decode a 'real' Set Timer HitachiAc3 message.
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1060#issuecomment-598631576
+TEST(TestDecodeHitachiAc3, RealSetTimerExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ const uint8_t expected[kHitachiAc3StateLength] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE8, 0x17, 0x89, 0x76, 0x0B,
+ 0xF4, 0x3F, 0xC0, 0x15, 0xEA, 0x00, 0xFF, 0x00, 0xFF, 0x4B, 0xB4, 0x18,
+ 0xE7, 0x00, 0xFF};
+ const uint16_t expectedBits = kHitachiAc3Bits;
+
+ const uint16_t rawData[435] = {
+ // Set Timer
+ 3364, 1668, 486, 1244, 458, 406, 456, 436, 430, 434, 430, 434, 456, 408,
+ 484, 432, 428, 432, 414, 450, 458, 432, 432, 432, 430, 436, 458, 1270,
+ 430, 408, 456, 408, 454, 462, 404, 460, 428, 408, 486, 404, 456, 408, 458,
+ 406, 484, 406, 456, 434, 432, 408, 484, 406, 454, 436, 404, 432, 486, 430,
+ 430, 408, 456, 432, 458, 1270, 406, 434, 456, 1246, 484, 1244, 456, 1274,
+ 432, 1244, 486, 1268, 432, 1244, 454, 412, 454, 1272, 430, 1272, 456,
+ 1274, 456, 1246, 456, 1244, 458, 1270, 458, 1246, 456, 1254, 450, 1246,
+ 484, 408, 456, 434, 430, 408, 486, 430, 404, 460, 430, 408, 486, 404, 458,
+ 406, 458, 406, 486, 404, 458, 432, 430, 1272, 456, 408, 458, 1244, 458,
+ 1244, 456, 1274, 456, 1246, 456, 1270, 460, 1250, 426, 460, 404, 1270,
+ 484, 432, 404, 462, 402, 460, 458, 1244, 456, 386, 452, 460, 458, 1244,
+ 458, 406, 458, 406, 486, 430, 416, 1260, 458, 406, 484, 1270, 406, 1296,
+ 430, 410, 482, 1246, 456, 1246, 456, 1246, 456, 434, 458, 1244, 456, 1272,
+ 458, 408, 458, 1244, 456, 410, 484, 404, 454, 410, 456, 408, 484, 406,
+ 458, 432, 430, 1246, 484, 406, 454, 1248, 458, 1244, 486, 1248, 428, 1270,
+ 456, 1266, 464, 1244, 458, 1246, 456, 1246, 484, 1270, 430, 1246, 456,
+ 434, 430, 460, 406, 432, 430, 432, 484, 432, 406, 432, 458, 406, 484, 432,
+ 432, 1266, 434, 1274, 430, 1298, 428, 408, 456, 1246, 486, 430, 432, 1270,
+ 404, 434, 484, 432, 430, 408, 456, 406, 460, 1268, 458, 408, 456, 1246,
+ 486, 406, 456, 1244, 456, 1248, 456, 1300, 430, 408, 456, 408, 484, 432,
+ 430, 434, 428, 434, 460, 430, 404, 434, 458, 406, 486, 1242, 458, 1270,
+ 430, 1246, 484, 1244, 456, 1270, 432, 1248, 484, 1244, 456, 1246, 456,
+ 408, 486, 404, 456, 408, 456, 432, 462, 430, 406, 458, 432, 432, 428,
+ 436, 456, 1246, 456, 1246, 484, 1244, 454, 1268, 438, 1244, 488, 1266,
+ 430, 1246, 458, 1244, 486, 1244, 430, 1298, 430, 434, 460, 1242, 458, 430,
+ 430, 408, 486, 1242, 456, 434, 404, 462, 456, 430, 432, 1246, 456, 408,
+ 486, 1270, 430, 1246, 460, 404, 482, 1246, 458, 406, 456, 408, 484, 404,
+ 458, 1270, 430, 1274, 458, 432, 430, 408, 456, 406, 486, 1244, 458, 1242,
+ 458, 1246, 484, 406, 458, 432, 430, 1246, 486, 1242, 456, 1272, 430, 434,
+ 458, 406, 458, 406, 458, 406, 486, 404, 458, 406, 458, 430, 430, 460, 430,
+ 1270, 430, 1248, 484, 1244, 456, 1244, 458, 1246, 484, 1244, 456, 1246,
+ 460, 1244, 458}; // UNKNOWN D3A5A0BA
+
+ irsend.reset();
+ irsend.sendRaw(rawData, 435, kHitachiAcFreq);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(expectedBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, expectedBits);
+}
+
+TEST(TestDecodeHitachiAc3, SyntheticSetTimerExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ const uint8_t expected[kHitachiAc3StateLength] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE8, 0x17, 0x89, 0x76, 0x0B,
+ 0xF4, 0x3F, 0xC0, 0x15, 0xEA, 0x00, 0xFF, 0x00, 0xFF, 0x4B, 0xB4, 0x18,
+ 0xE7, 0x00, 0xFF};
+
+ irsend.reset();
+ irsend.sendHitachiAc3(expected, kHitachiAc3StateLength);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(kHitachiAc3Bits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
+}
+
+// Decode a 'real' Change Mode HitachiAc3 message.
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1060#issuecomment-598631576
+TEST(TestDecodeHitachiAc3, RealChangeModeExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ const uint8_t expected[kHitachiAc3StateLength - 6] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE5, 0x1A, 0x89, 0x76, 0x04,
+ 0xFB, 0x3F, 0xC0, 0x1B, 0xE4, 0x14, 0xEB, 0x02, 0xFD};
+ const uint16_t expectedBits = kHitachiAc3Bits - 6 * 8;
+
+ const uint16_t rawData[339] = {
+ // Change Mode
+ 3364, 1666, 488, 1268, 404, 434, 454, 434, 460, 404, 458, 406, 458, 406,
+ 484, 432, 432, 430, 432, 408, 484, 406, 458, 432, 432, 406, 486, 1242,
+ 458, 430, 430, 408, 454, 436, 456, 408, 458, 406, 484, 432, 428, 434, 430,
+ 408, 484, 406, 458, 430, 432, 408, 484, 430, 430, 432, 432, 408, 482, 408,
+ 456, 408, 458, 432, 458, 1246, 458, 430, 430, 1246, 486, 1242, 458, 1270,
+ 432, 1246, 486, 1242, 458, 1268, 432, 434, 430, 1272, 456, 1246, 458,
+ 1270, 460, 1244, 458, 1246, 456, 1272, 460, 1242, 456, 1270, 434, 1246,
+ 486, 430, 430, 434, 432, 406, 484, 430, 432, 432, 430, 408, 484, 432, 432,
+ 432, 430, 1246, 484, 406, 458, 1246, 456, 408, 486, 404, 458, 1268, 434,
+ 1270, 430, 1274, 456, 408, 458, 1270, 460, 404, 458, 1244, 458, 1246, 486,
+ 430, 430, 432, 460, 378, 488, 1240, 460, 404, 458, 408, 486, 1242, 458,
+ 432, 430, 434, 460, 430, 432, 1246, 458, 406, 488, 1240, 430, 1272, 458,
+ 406, 486, 1242, 430, 1298, 430, 1274, 428, 432, 430, 436, 456, 408, 482,
+ 1248, 458, 406, 430, 462, 456, 404, 458, 432, 430, 408, 486, 1266, 436,
+ 1242, 458, 406, 486, 1242, 456, 1246, 458, 1244, 488, 1240, 458, 1244,
+ 458, 1272, 460, 1242, 456, 1246, 458, 1246, 486, 1242, 458, 1270, 432,
+ 406, 458, 458, 434, 430, 432, 406, 486, 406, 456, 408, 458, 432, 484, 406,
+ 430, 1272, 460, 1216, 486, 1242, 456, 1246, 458, 406, 486, 1268, 432,
+ 1244, 458, 406, 486, 404, 460, 432, 430, 406, 488, 402, 458, 1272, 428,
+ 434, 460, 404, 460, 1242, 458, 1246, 480, 1244, 462, 428, 432, 432, 460,
+ 1244, 458, 432, 430, 1246, 488, 402, 456, 408, 458, 406, 486, 1268, 432,
+ 1246, 460, 430, 460, 1244, 458, 406, 458, 1244, 486, 1242, 458, 1244, 458,
+ 432, 462, 1242, 456, 408, 456, 406, 486, 428, 434, 406, 458, 406, 456,
+ 434, 458, 1244, 460, 430, 462, 1240, 458, 1244, 460, 1244, 486, 1244, 458,
+ 1242, 488, 1214, 460}; // UNKNOWN C1EA1036
+
+ irsend.reset();
+ irsend.sendRaw(rawData, 339, kHitachiAcFreq);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(expectedBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, expectedBits);
+}
+
+TEST(TestDecodeHitachiAc3, SyntheticChangeModeExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ const uint8_t expected[kHitachiAc3StateLength - 6] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE5, 0x1A, 0x89, 0x76, 0x04,
+ 0xFB, 0x3F, 0xC0, 0x1B, 0xE4, 0x14, 0xEB, 0x02, 0xFD};
+ const uint16_t expectedBits = kHitachiAc3Bits - 6 * 8;
+
+ irsend.reset();
+ irsend.sendHitachiAc3(expected, kHitachiAc3StateLength - 6);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(HITACHI_AC3, irsend.capture.decode_type);
+ ASSERT_EQ(expectedBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
+}
+
+TEST(TestHitachiAc3Class, hasInvertedStates) {
+ const uint8_t good_state[kHitachiAc3StateLength] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE8, 0x17, 0x89, 0x76, 0x0B,
+ 0xF4, 0x3F, 0xC0, 0x15, 0xEA, 0x00, 0xFF, 0x00, 0xFF, 0x4B, 0xB4, 0x18,
+ 0xE7, 0x00, 0xFF};
+ // bad_state[kHitachiAc3MinStateLength + 1] has been modified to be different.
+ // i.e. Anything larger than kHitachiAc3MinStateLength should fail.
+ // kHitachiAc3MinStateLength or shorter should pass.
+ const uint8_t bad_state[kHitachiAc3StateLength] = {
+ 0x01, 0x10, 0x00, 0x40, 0xBF, 0xFF, 0x00, 0xE8, 0x17, 0x89, 0x76, 0x0B,
+ 0xF4, 0x3F, 0xC0, 0x15, 0xE0, 0x00, 0xFF, 0x00, 0xFF, 0x4B, 0xB4, 0x18,
+ 0xE7, 0x00, 0xFF};
+
+ EXPECT_TRUE(IRHitachiAc3::hasInvertedStates(good_state,
+ kHitachiAc3StateLength));
+
+ for (uint8_t len = kHitachiAc3StateLength;
+ len > kHitachiAc3MinStateLength;
+ len -= 2) {
+ EXPECT_FALSE(IRHitachiAc3::hasInvertedStates(bad_state, len));
+ }
+ EXPECT_TRUE(IRHitachiAc3::hasInvertedStates(bad_state,
+ kHitachiAc3MinStateLength));
+ EXPECT_TRUE(IRHitachiAc3::hasInvertedStates(bad_state,
+ kHitachiAc3MinStateLength - 2));
+}
+
+// HitachiAc1 Class tests
+
+TEST(TestIRHitachiAc1Class, SetAndGetPower) {
+ IRHitachiAc1 ac(kGpioUnused);
+ ac.on();
+ ac.setPowerToggle(false);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_FALSE(ac.getPowerToggle());
+ ac.off();
+ EXPECT_FALSE(ac.getPower());
+ EXPECT_TRUE(ac.getPowerToggle());
+ ac.setPowerToggle(false);
+ EXPECT_FALSE(ac.getPowerToggle());
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_TRUE(ac.getPowerToggle());
+ ac.setPower(false);
+ EXPECT_FALSE(ac.getPower());
+ EXPECT_TRUE(ac.getPowerToggle());
+}
+
+TEST(TestIRHitachiAc1Class, SetAndGetTemp) {
+ IRHitachiAc1 ac(kGpioUnused);
+ ac.setMode(kHitachiAc1Cool); // All temps possible in Cool mode.
+ ac.setTemp(26);
+ EXPECT_EQ(26, ac.getTemp());
+ ac.setTemp(kHitachiAcMinTemp);
+ EXPECT_EQ(kHitachiAcMinTemp, ac.getTemp());
+ ac.setTemp(kHitachiAcMinTemp - 1);
+ EXPECT_EQ(kHitachiAcMinTemp, ac.getTemp());
+ ac.setTemp(kHitachiAcMaxTemp);
+ EXPECT_EQ(kHitachiAcMaxTemp, ac.getTemp());
+ ac.setTemp(kHitachiAcMaxTemp + 1);
+ EXPECT_EQ(kHitachiAcMaxTemp, ac.getTemp());
+
+ // Can't change temp in Auto mode.
+ ac.setMode(kHitachiAc1Auto); // All temps possible in Cool mode.
+ EXPECT_EQ(kHitachiAc1TempAuto, ac.getTemp());
+ ac.setTemp(kHitachiAcMinTemp);
+ EXPECT_EQ(kHitachiAc1TempAuto, ac.getTemp());
+
+ // Ref: https://docs.google.com/spreadsheets/d/10eKpJEWJppUYktPRLCcAIwzfFXjtkOZNyn1reh5MFfU/edit#gid=0&range=B46
+ const uint8_t cool_31_auto[kHitachiAc1StateLength] = {
+ 0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0x61, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x68};
+ ac.setRaw(cool_31_auto);
+ EXPECT_EQ(31, ac.getTemp());
+}
+
+TEST(TestIRHitachiAc1Class, SetAndGetMode) {
+ IRHitachiAc1 ac(kGpioUnused);
+ ac.setMode(kHitachiAc1Auto);
+ EXPECT_EQ(kHitachiAc1Auto, ac.getMode());
+ ac.setMode(kHitachiAc1Cool);
+ EXPECT_EQ(kHitachiAc1Cool, ac.getMode());
+ ac.setMode(kHitachiAc1Fan);
+ EXPECT_EQ(kHitachiAc1Fan, ac.getMode());
+ ac.setMode(kHitachiAc1Heat);
+ EXPECT_EQ(kHitachiAc1Heat, ac.getMode());
+ ac.setMode(kHitachiAc1Dry);
+ EXPECT_EQ(kHitachiAc1Dry, ac.getMode());
+ ac.setMode(0);
+ EXPECT_EQ(kHitachiAc1Auto, ac.getMode());
+ ac.setMode(255);
+ EXPECT_EQ(kHitachiAc1Auto, ac.getMode());
+}
+
+TEST(TestIRHitachiAc1Class, SetAndGetFan) {
+ IRHitachiAc1 ac(kGpioUnused);
+ ac.setMode(kHitachiAc1Cool); // All speeds possible in Cool mode.
+ ac.setFan(kHitachiAc1FanAuto);
+ EXPECT_EQ(kHitachiAc1FanAuto, ac.getFan());
+ ac.setFan(kHitachiAc1FanLow);
+ EXPECT_EQ(kHitachiAc1FanLow, ac.getFan());
+ ac.setFan(kHitachiAc1FanHigh);
+ EXPECT_EQ(kHitachiAc1FanHigh, ac.getFan());
+ ac.setFan(kHitachiAc1FanMed);
+ EXPECT_EQ(kHitachiAc1FanMed, ac.getFan());
+
+ ac.setFan(255);
+ EXPECT_EQ(kHitachiAc1FanAuto, ac.getFan());
+ ac.setFan(0);
+ EXPECT_EQ(kHitachiAc1FanAuto, ac.getFan());
+
+ // Can't change speed in Auto mode. Locked to auto speed.
+ ac.setMode(kHitachiAc1Auto);
+ EXPECT_EQ(kHitachiAc1FanAuto, ac.getFan());
+ ac.setFan(kHitachiAc1FanLow);
+ EXPECT_EQ(kHitachiAc1FanAuto, ac.getFan());
+ // Can't change speed in Dry mode. Locked to low speed.
+ ac.setMode(kHitachiAc1Dry);
+ EXPECT_EQ(kHitachiAc1FanLow, ac.getFan());
+ ac.setFan(kHitachiAc1FanHigh);
+ EXPECT_EQ(kHitachiAc1FanLow, ac.getFan());
+}
+
+TEST(TestIRHitachiAc1Class, HumanReadable) {
+ IRHitachiAc1 ac(kGpioUnused);
+
+ // Ref: https://docs.google.com/spreadsheets/d/10eKpJEWJppUYktPRLCcAIwzfFXjtkOZNyn1reh5MFfU/edit#gid=0&range=A47:B47
+ const uint8_t cool_32_auto[kHitachiAc1StateLength] = {
+ 0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0x61, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x30,
+ 0x04};
+ ac.setRaw(cool_32_auto);
+ EXPECT_EQ(
+ "Model: 1 (R-LT0541-HTA-A), Power: On, Power Toggle: On, Mode: 6 (Cool), "
+ "Temp: 32C, Fan: 1 (Auto), Swing(V) Toggle: Off, "
+ "Swing(V): Off, Swing(H): Off, "
+ "Sleep: Off, On Timer: Off, Off Timer: Off",
+ ac.toString());
+ ac.setModel(hitachi_ac1_remote_model_t::R_LT0541_HTA_B);
+ ac.setSwingV(true);
+ ac.setSwingToggle(true);
+ ac.setSleep(kHitachiAc1Sleep2);
+ ac.setPowerToggle(false);
+ ac.setOnTimer(2 * 60 + 39);
+ ac.setOffTimer(10 * 60 + 17);
+ EXPECT_EQ(
+ "Model: 2 (R-LT0541-HTA-B), Power: On, Power Toggle: Off, "
+ "Mode: 6 (Cool), Temp: 32C, Fan: 1 (Auto), "
+ "Swing(V) Toggle: On, Swing(V): On, Swing(H): Off, Sleep: 2, "
+ "On Timer: 02:39, Off Timer: 10:17",
+ ac.toString());
+}
+
+TEST(TestIRHitachiAc1Class, Checksum) {
+ // Reverse Table: 2=4, B=D, A=5, E=7, 1=8, 3=C, 0=0, 6=6, 9=9, F=F
+ IRHitachiAc1 ac(kGpioUnused);
+ // Ref: https://docs.google.com/spreadsheets/d/10eKpJEWJppUYktPRLCcAIwzfFXjtkOZNyn1reh5MFfU/edit#gid=0&range=A47:B47
+ const uint8_t cool_32_auto[kHitachiAc1StateLength] = {
+ 0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0x61, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x30,
+ 0x04};
+ // Reversed: 4D, 75, B2, 89, 0F, 86, 33, 00, 00, 00, 00, 0C, 20
+ EXPECT_TRUE(ac.validChecksum(cool_32_auto));
+ EXPECT_EQ(0x04, ac.calcChecksum(cool_32_auto));
+
+ // Ref: https://docs.google.com/spreadsheets/d/10eKpJEWJppUYktPRLCcAIwzfFXjtkOZNyn1reh5MFfU/edit#gid=0&range=B46
+ const uint8_t cool_31_auto[kHitachiAc1StateLength] = {
+ 0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0x61, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x68};
+ // Reversed: 4D, 75, B2, 89, 0F, 86, 31, 00, 00, 00, 00, 04, 16
+ EXPECT_TRUE(ac.validChecksum(cool_31_auto));
+ EXPECT_EQ(0x68, ac.calcChecksum(cool_31_auto));
+
+ // Ref: https://docs.google.com/spreadsheets/d/10eKpJEWJppUYktPRLCcAIwzfFXjtkOZNyn1reh5MFfU/edit#gid=0&range=B13
+ const uint8_t auto_25_auto_swing_on[kHitachiAc1StateLength] = {
+ 0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0xE1, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x61,
+ 0x24};
+ // Reversed: 4D, 75, B2, 89, 0F, 87, 25, 00, 00, 00, 00, 86, 42
+ EXPECT_TRUE(ac.validChecksum(auto_25_auto_swing_on));
+ EXPECT_EQ(0x24, ac.calcChecksum(auto_25_auto_swing_on));
+ // Ref: https://docs.google.com/spreadsheets/d/10eKpJEWJppUYktPRLCcAIwzfFXjtkOZNyn1reh5MFfU/edit#gid=0&range=B45
+ const uint8_t cool_30_auto[kHitachiAc1StateLength] = {
+ 0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0x61, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0xC4};
+ EXPECT_TRUE(ac.validChecksum(cool_30_auto));
+ EXPECT_EQ(0xC4, ac.calcChecksum(cool_30_auto));
+}
+
+TEST(TestIRHitachiAc1Class, toCommon) {
+ IRHitachiAc1 ac(kGpioUnused);
+ ac.setPower(true);
+ ac.setMode(kHitachiAc1Cool);
+ ac.setTemp(20);
+ ac.setFan(kHitachiAc1FanHigh);
+ ac.setSwingV(false);
+ ac.setSwingH(true);
+ ac.setModel(hitachi_ac1_remote_model_t::R_LT0541_HTA_B);
+ // Now test it.
+ ASSERT_EQ(decode_type_t::HITACHI_AC1, ac.toCommon().protocol);
+ ASSERT_EQ(2, ac.toCommon().model);
+ ASSERT_TRUE(ac.toCommon().power);
+ ASSERT_TRUE(ac.toCommon().celsius);
+ ASSERT_EQ(20, ac.toCommon().degrees);
+ ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
+ ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
+ ASSERT_EQ(stdAc::swingv_t::kOff, ac.toCommon().swingv);
+ ASSERT_EQ(stdAc::swingh_t::kAuto, ac.toCommon().swingh);
+ // Unsupported.
+ ASSERT_FALSE(ac.toCommon().turbo);
+ ASSERT_FALSE(ac.toCommon().clean);
+ ASSERT_FALSE(ac.toCommon().light);
+ ASSERT_FALSE(ac.toCommon().quiet);
+ ASSERT_FALSE(ac.toCommon().econo);
+ ASSERT_FALSE(ac.toCommon().filter);
+ ASSERT_FALSE(ac.toCommon().beep);
+ ASSERT_EQ(-1, ac.toCommon().sleep);
+ ASSERT_EQ(-1, ac.toCommon().clock);
+}
+
+TEST(TestIRHitachiAc1Class, ReconstructKnownGood) {
+ IRHitachiAc1 ac(kGpioUnused);
+ const uint8_t known_good[kHitachiAc1StateLength] = {
+ 0xB2, 0xAE, 0x4D, 0x51, 0xF0, 0x61, 0x84,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x98};
+ ac.stateReset();
+ ac.setPower(false);
+ ac.setPowerToggle(true);
+ ac.setMode(kHitachiAc1Cool);
+ ac.setTemp(23);
+ ac.setFan(kHitachiAc1FanAuto);
+ ac.setSwingV(false);
+ ac.setSwingH(false);
+ ac.setSwingToggle(false);
+ ac.setModel(hitachi_ac1_remote_model_t::R_LT0541_HTA_B);
+
+ EXPECT_STATE_EQ(known_good, ac.getRaw(), kHitachiAc1Bits);
+ EXPECT_EQ(
+ "Model: 2 (R-LT0541-HTA-B), Power: Off, Power Toggle: On, "
+ "Mode: 6 (Cool), Temp: 23C, Fan: 1 (Auto), "
+ "Swing(V) Toggle: Off, Swing(V): Off, Swing(H): Off, Sleep: Off, "
+ "On Timer: Off, Off Timer: Off",
+ ac.toString());
+}
+
+TEST(TestIRHitachiAc1Class, Swing) {
+ IRHitachiAc1 ac(kGpioUnused);
+ ac.setSwingV(false);
+ EXPECT_FALSE(ac.getSwingV());
+ ac.setSwingToggle(false);
+ EXPECT_FALSE(ac.getSwingToggle());
+
+ ac.setSwingV(true);
+ EXPECT_TRUE(ac.getSwingV());
+ EXPECT_FALSE(ac.getSwingToggle());
+ ac.setSwingToggle(true);
+ EXPECT_TRUE(ac.getSwingV());
+ EXPECT_TRUE(ac.getSwingToggle());
+
+ ac.setSwingV(false);
+ EXPECT_FALSE(ac.getSwingV());
+ ac.setSwingToggle(false);
+ EXPECT_FALSE(ac.getSwingToggle());
+
+ const uint8_t swing_on_with_toggle[kHitachiAc1StateLength] = {
+ 0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0xE1, 0xA4,
+ 0x00, 0x00, 0x00, 0x00, 0x61, 0x24};
+ ac.setRaw(swing_on_with_toggle);
+ EXPECT_TRUE(ac.getSwingV());
+ EXPECT_FALSE(ac.getSwingH());
+ EXPECT_TRUE(ac.getSwingToggle());
+ const uint8_t swing_off_with_toggle[kHitachiAc1StateLength] = {
+ 0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0xE1, 0xA4,
+ 0x00, 0x00, 0x00, 0x00, 0x21, 0x44};
+ ac.setRaw(swing_off_with_toggle);
+ EXPECT_FALSE(ac.getSwingV());
+ EXPECT_FALSE(ac.getSwingH());
+ EXPECT_TRUE(ac.getSwingToggle());
+ ac.setSwingToggle(true);
+ EXPECT_STATE_EQ(swing_off_with_toggle, ac.getRaw(), kHitachiAc1Bits);
+}
+
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1056#issuecomment-609374682
+TEST(TestIRHitachiAc1Class, FanSpeedInDryMode) {
+ IRHitachiAc1 ac(kGpioUnused);
+ // IRhvac {"Vendor":"HITACHI_AC1", "Power":"On","Mode":"dry","FanSpeed":"low"
+ // "Temp":22.5}
+ const uint8_t state[kHitachiAc1StateLength] = { // Code generated by Tasmota.
+ 0xB2, 0xAE, 0x4D, 0x91, 0xF0, 0x21, 0xF8,
+ 0x00, 0x00, 0x00, 0x00, 0x31, 0x0C};
+ ac.setRaw(state);
+ EXPECT_EQ(
+ "Model: 1 (R-LT0541-HTA-A), Power: On, Power Toggle: On, Mode: 2 (Dry), "
+ "Temp: 22C, Fan: 1 (Auto), "
+ "Swing(V) Toggle: On, Swing(V): Off, Swing(H): Off, Sleep: Off, "
+ "On Timer: Off, Off Timer: Off",
+ ac.toString());
+ ac.stateReset();
+ // Build it via the build order in IRac::hitachi1()
+ ac.setModel(hitachi_ac1_remote_model_t::R_LT0541_HTA_A);
+ ac.setPower(true);
+ ac.setPowerToggle(true);
+ ac.setMode(kHitachiAc1Dry);
+ ac.setTemp(22.5);
+ ac.setFan(kHitachiAc1FanLow);
+ ac.setSwingV(false);
+ ac.setSwingH(false);
+ ac.setSwingToggle(true);
+ ac.setSleep(0);
+ EXPECT_EQ(
+ "Model: 1 (R-LT0541-HTA-A), Power: On, Power Toggle: On, Mode: 2 (Dry), "
+ "Temp: 22C, Fan: 8 (Low), "
+ "Swing(V) Toggle: On, Swing(V): Off, Swing(H): Off, Sleep: Off, "
+ "On Timer: Off, Off Timer: Off",
+ ac.toString());
+}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Inax_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Inax_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Inax_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Inax_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_JVC_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_JVC_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_JVC_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_JVC_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Kelvinator_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Kelvinator_test.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Kelvinator_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Kelvinator_test.cpp
index e01a585bd..73ad6581d 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Kelvinator_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Kelvinator_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 David Conran
#include "ir_Kelvinator.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRremoteESP8266.h"
@@ -519,6 +520,13 @@ TEST(TestDecodeKelvinator, NormalSynthetic) {
EXPECT_EQ(KELVINATOR, irsend.capture.decode_type);
ASSERT_EQ(kKelvinatorBits, irsend.capture.bits);
EXPECT_STATE_EQ(kelv_code, irsend.capture.state, kKelvinatorBits);
+ EXPECT_EQ(
+ "Power: On, Mode: 1 (Cool), Temp: 27C, Fan: 1 (Low), Turbo: Off, "
+ "Quiet: Off, XFan: On, Ion: Off, Light: Off, "
+ "Swing(H): Off, Swing(V): Off",
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestKelvinatorClass, toCommon) {
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_LG_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_LG_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_LG_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_LG_test.cpp
index 703ea3c6c..3c04c902f 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_LG_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_LG_test.cpp
@@ -843,6 +843,8 @@ TEST(TestDecodeLG2, Issue1008) {
ASSERT_EQ(LG2, ac._irsend.capture.decode_type);
ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRLgAcClass, DifferentModels) {
@@ -864,6 +866,8 @@ TEST(TestIRLgAcClass, DifferentModels) {
ASSERT_EQ(LG, ac._irsend.capture.decode_type); // Not "LG2"
ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
ASSERT_EQ(expected1, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
ac.setModel(lg_ac_remote_model_t::AKB75215403); // aka. 2
@@ -879,4 +883,5 @@ TEST(TestIRLgAcClass, DifferentModels) {
ASSERT_EQ(LG2, ac._irsend.capture.decode_type); // Not "LG"
ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
ASSERT_EQ(expected2, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Lasertag_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Lasertag_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Lasertag_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Lasertag_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Lego_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Lego_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Lego_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Lego_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Lutron_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Lutron_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Lutron_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Lutron_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_MWM_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_MWM_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_MWM_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_MWM_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Magiquest_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Magiquest_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Magiquest_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Magiquest_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Midea_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Midea_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Midea_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Midea_test.cpp
index a43076fea..4c437a576 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Midea_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Midea_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 David Conran
#include "ir_Midea.h"
+#include "IRac.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "gtest/gtest.h"
@@ -669,6 +670,12 @@ TEST(TestDecodeMidea, DecodeRealExample) {
EXPECT_EQ(MIDEA, irsend.capture.decode_type);
EXPECT_EQ(kMideaBits, irsend.capture.bits);
EXPECT_EQ(0xA18263FFFF6E, irsend.capture.value);
+ EXPECT_EQ(
+ "Power: On, Mode: 2 (Auto), Celsius: Off, Temp: 18C/65F, Fan: 0 (Auto), "
+ "Sleep: Off, Swing(V) Toggle: Off",
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestMideaACClass, toCommon) {
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_MitsubishiHeavy_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_MitsubishiHeavy_test.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/test/ir_MitsubishiHeavy_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_MitsubishiHeavy_test.cpp
index a8226feb8..d182fd941 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_MitsubishiHeavy_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_MitsubishiHeavy_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2019 David Conran
#include "ir_MitsubishiHeavy.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRremoteESP8266.h"
@@ -742,7 +743,9 @@ TEST(TestDecodeMitsubishiHeavy, ZmsRealExample) {
"Power: On, Mode: 4 (Heat), Temp: 24C, Fan: 4 (Max), "
"Swing(V): 0 (Auto), Swing(H): 0 (Auto), Silent: Off, Turbo: Off, "
"Econo: Off, Night: Off, Filter: Off, 3D: Off, Clean: Off",
- ac.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Decode a Synthetic MitsubishiHeavy 152Bit message.
@@ -847,7 +850,9 @@ TEST(TestDecodeMitsubishiHeavy, ZjsSyntheticExample) {
"Power: On, Mode: 2 (Dry), Temp: 25C, Fan: 0 (Auto), "
"Swing(V): 0 (Off), Swing(H): 6 (Left Right), Turbo: Off, Econo: Off, "
"3D: Off, Clean: Off",
- ac.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestMitsubishiHeavy152AcClass, toCommon) {
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Mitsubishi_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Mitsubishi_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Mitsubishi_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Mitsubishi_test.cpp
index 4f759c046..8e1c1bf51 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Mitsubishi_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Mitsubishi_test.cpp
@@ -1230,6 +1230,8 @@ TEST(TestDecodeMitsubishi136, DecodeRealExample) {
"Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 3 (High), "
"Swing(V): 3 (Highest), Quiet: Off",
IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Self decode a synthetic example.
@@ -1719,6 +1721,8 @@ TEST(TestDecodeMitsubishi112, DecodeRealExample) {
"Power: On, Mode: 3 (Cool), Temp: 23C, Fan: 2 (Quiet), "
"Swing(V): 7 (Auto), Swing(H): 12 (Auto), Quiet: On",
IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Self decode a synthetic example.
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_NEC_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_NEC_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_NEC_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_NEC_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Neoclima_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Neoclima_test.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Neoclima_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Neoclima_test.cpp
index c743e7ba5..b395ee8dd 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Neoclima_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Neoclima_test.cpp
@@ -2,6 +2,7 @@
#include "ir_Neoclima.h"
#include
+#include "IRac.h"
#include "IRsend.h"
#include "IRsend_test.h"
#include "IRrecv.h"
@@ -12,6 +13,7 @@ TEST(TestUtils, Housekeeping) {
ASSERT_EQ("NEOCLIMA", typeToString(decode_type_t::NEOCLIMA));
ASSERT_EQ(decode_type_t::NEOCLIMA, strToDecodeType("NEOCLIMA"));
ASSERT_TRUE(hasACState(decode_type_t::NEOCLIMA));
+ ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::NEOCLIMA));
}
// Test sending typical data only.
@@ -83,7 +85,9 @@ TEST(TestDecodeNeoclima, RealExample) {
"Swing(V): Off, Swing(H): On, Sleep: Off, Turbo: Off, Hold: Off, "
"Ion: Off, Eye: Off, Light: Off, Follow: Off, 8C Heat: Off, Fresh: Off, "
"Button: 0 (Power)",
- ac.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Self decode.
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Nikai_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Nikai_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Nikai_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Nikai_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Panasonic_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Panasonic_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Panasonic_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Panasonic_test.cpp
index 7f022ed17..fbce6de4e 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Panasonic_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Panasonic_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2017, 2018 David Conran
#include "ir_Panasonic.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -889,14 +890,13 @@ TEST(TestDecodePanasonicAC, SyntheticExample) {
EXPECT_EQ(kPanasonicAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_FALSE(irsend.capture.repeat);
-
- IRPanasonicAc pana(0);
- pana.setRaw(irsend.capture.state);
EXPECT_EQ(
"Model: 4 (JKE), Power: Off, Mode: 3 (Cool), Temp: 25C, "
"Fan: 7 (Auto), Swing(V): 15 (Auto), Quiet: Off, "
"Powerful: Off, Clock: 00:00, On Timer: Off, Off Timer: Off",
- pana.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Tests for general utility functions.
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Pioneer_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Pioneer_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Pioneer_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Pioneer_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Pronto_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Pronto_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Pronto_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Pronto_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_RC5_RC6_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_RC5_RC6_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_RC5_RC6_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_RC5_RC6_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_RCMM_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_RCMM_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_RCMM_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_RCMM_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Samsung_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Samsung_test.cpp
similarity index 94%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Samsung_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Samsung_test.cpp
index c44572934..52165b780 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Samsung_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Samsung_test.cpp
@@ -1,7 +1,8 @@
-// Copyright 2017, 2018, 2019 David Conran
+// Copyright 2017-2020 David Conran
#include
#include "ir_Samsung.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -571,6 +572,13 @@ TEST(TestIRSamsungAcClass, SetAndGetPowerful) {
EXPECT_FALSE(ac.getPowerful());
EXPECT_EQ(kSamsungAcFanAuto, ac.getFan());
+ // Breeze and Powerful/Turbo are mutually exclusive.
+ ac.setPowerful(true);
+ EXPECT_TRUE(ac.getPowerful());
+ ac.setBreeze(true);
+ EXPECT_TRUE(ac.getBreeze());
+ EXPECT_FALSE(ac.getPowerful());
+
// Actual powerful on & off states from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/734#issuecomment-500120270
uint8_t on[kSamsungAcStateLength] = {
@@ -581,7 +589,8 @@ TEST(TestIRSamsungAcClass, SetAndGetPowerful) {
EXPECT_EQ(kSamsungAcFanTurbo, ac.getFan());
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 7 (Turbo), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: On, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: On, Breeze: Off, "
+ "Light: On, Ion: Off",
ac.toString());
uint8_t off[kSamsungAcStateLength] = {
@@ -592,7 +601,8 @@ TEST(TestIRSamsungAcClass, SetAndGetPowerful) {
EXPECT_NE(kSamsungAcFanTurbo, ac.getFan());
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
ac.toString());
}
@@ -658,7 +668,8 @@ TEST(TestIRSamsungAcClass, HumanReadable) {
IRSamsungAc samsung(0);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 2 (Low), Swing: On, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
samsung.setTemp(kSamsungAcMaxTemp);
samsung.setMode(kSamsungAcHeat);
@@ -669,24 +680,28 @@ TEST(TestIRSamsungAcClass, HumanReadable) {
samsung.setClean(true);
EXPECT_EQ(
"Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 5 (High), Swing: Off, "
- "Beep: On, Clean: On, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: On, Clean: On, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
samsung.setQuiet(true);
EXPECT_EQ(
"Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 0 (Auto), Swing: Off, "
- "Beep: On, Clean: On, Quiet: On, Powerful: Off, Light: On, Ion: Off",
+ "Beep: On, Clean: On, Quiet: On, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
samsung.setQuiet(false);
samsung.setPowerful(true);
EXPECT_EQ(
"Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 7 (Turbo), Swing: Off, "
- "Beep: On, Clean: On, Quiet: Off, Powerful: On, Light: On, Ion: Off",
+ "Beep: On, Clean: On, Quiet: Off, Powerful: On, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
samsung.setIon(true);
samsung.setDisplay(false);
EXPECT_EQ(
"Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 7 (Turbo), Swing: Off, "
- "Beep: On, Clean: On, Quiet: Off, Powerful: On, Light: Off, Ion: On",
+ "Beep: On, Clean: On, Quiet: Off, Powerful: On, Breeze: Off, "
+ "Light: Off, Ion: On",
samsung.toString());
}
@@ -790,7 +805,8 @@ TEST(TestDecodeSamsungAC, DecodeRealExample) {
samsung.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 2 (Low), Swing: On, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
}
@@ -839,7 +855,8 @@ TEST(TestDecodeSamsungAC, DecodeRealExample2) {
samsung.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
}
@@ -898,7 +915,8 @@ TEST(TestDecodeSamsungAC, DecodePowerOnSample) {
samsung.setRaw(irsend.capture.state, kSamsungAcExtendedStateLength);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
}
@@ -958,7 +976,8 @@ TEST(TestDecodeSamsungAC, DecodePowerOffSample) {
samsung.setRaw(irsend.capture.state, kSamsungAcExtendedStateLength);
EXPECT_EQ(
"Power: Off, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
}
@@ -1005,7 +1024,8 @@ TEST(TestDecodeSamsungAC, DecodeHeatSample) {
samsung.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 4 (Heat), Temp: 17C, Fan: 0 (Auto), Swing: On, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
}
@@ -1047,13 +1067,13 @@ TEST(TestDecodeSamsungAC, DecodeCoolSample) {
ASSERT_EQ(SAMSUNG_AC, irsend.capture.decode_type);
EXPECT_EQ(kSamsungAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
-
- IRSamsungAc samsung(0);
- samsung.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
- samsung.toString());
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestDecodeSamsungAC, Issue604DecodeExtended) {
@@ -1110,7 +1130,8 @@ TEST(TestDecodeSamsungAC, Issue604DecodeExtended) {
samsung.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(
"Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
samsung.toString());
}
@@ -1307,7 +1328,7 @@ TEST(TestIRSamsungAcClass, Issue604SendPowerHack) {
"m586s100000";
std::string text = "Power: On, Mode: 1 (Cool), Temp: 23C, Fan: 4 (Med), "
"Swing: On, Beep: Off, Clean: Off, Quiet: Off, "
- "Powerful: Off, Light: On, Ion: Off";
+ "Powerful: Off, Breeze: Off, Light: On, Ion: Off";
// Don't do a setPower()/on()/off() as that will trigger the special message.
// So it should only be the normal "settings" message.
ac.setTemp(23);
@@ -1434,7 +1455,8 @@ TEST(TestDecodeSamsungAC, Issue734QuietSetting) {
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: On, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: On, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
ac.toString());
// Make sure the ac class state is in something wildly different first.
@@ -1456,7 +1478,8 @@ TEST(TestDecodeSamsungAC, Issue734QuietSetting) {
ac.setQuiet(true);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: On, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: On, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
ac.toString());
// Check it matches the known good/expected state.
EXPECT_STATE_EQ(expectedState, ac.getRaw(), kSamsungAcBits);
@@ -1506,6 +1529,52 @@ TEST(TestDecodeSamsungAC, Issue734PowerfulOff) {
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Light: On, Ion: Off",
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
+ ac.toString());
+}
+
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
+TEST(TestIRSamsungAcClass, SetAndGetBreeze) {
+ IRSamsungAc ac(kGpioUnused);
+ ac.setFan(kSamsungAcFanMed);
+ ac.setBreeze(false);
+ EXPECT_FALSE(ac.getBreeze());
+ EXPECT_EQ(kSamsungAcFanMed, ac.getFan());
+ ac.setBreeze(true);
+ EXPECT_TRUE(ac.getBreeze());
+ EXPECT_EQ(kSamsungAcFanAuto, ac.getFan()); // Breeze sets fan to auto.
+ ac.setBreeze(false);
+ EXPECT_FALSE(ac.getBreeze());
+ EXPECT_EQ(kSamsungAcFanAuto, ac.getFan());
+
+ // Breeze and Powerful/Turbo are mutually exclusive.
+ ac.setBreeze(true);
+ EXPECT_TRUE(ac.getBreeze());
+ ac.setPowerful(true);
+ EXPECT_FALSE(ac.getBreeze());
+
+ // Check against real messages.
+ // MODE FAN, 24C WINDFREE ON
+ const uint8_t on[14] = {
+ 0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x01, 0xB2, 0xFE, 0x7B, 0x80,
+ 0x31, 0xF0};
+ ac.setRaw(on);
+ ASSERT_TRUE(ac.getBreeze());
+ EXPECT_EQ(
+ "Power: On, Mode: 3 (Fan), Temp: 24C, Fan: 0 (Auto), Swing: Off, "
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: On, "
+ "Light: On, Ion: Off",
+ ac.toString());
+ // MODE FAN, 24C WINDFREE OFF, FAN = LOW
+ const uint8_t off[14] = {
+ 0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0, 0x01, 0xC2, 0xFE, 0x71, 0x80,
+ 0x35, 0xF0};
+ ac.setRaw(off);
+ ASSERT_FALSE(ac.getBreeze());
+ EXPECT_EQ(
+ "Power: On, Mode: 3 (Fan), Temp: 24C, Fan: 2 (Low), Swing: Off, "
+ "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
+ "Light: On, Ion: Off",
ac.toString());
}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Sanyo_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Sanyo_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Sanyo_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Sanyo_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Sharp_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Sharp_test.cpp
similarity index 83%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Sharp_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Sharp_test.cpp
index e605e0d05..173c94f2a 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Sharp_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Sharp_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2017 David Conran
#include "ir_Sharp.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -407,12 +408,11 @@ TEST(TestDecodeSharpAc, RealExample) {
ASSERT_EQ(SHARP_AC, irsend.capture.decode_type);
ASSERT_EQ(kSharpAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
-
- IRSharpAc ac(0);
- ac.begin();
- ac.setRaw(irsend.capture.state);
- EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 27C, Fan: 2 (Auto)",
- ac.toString());
+ EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 27C, "
+ "Fan: 2 (Auto)",
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// https://github.com/crankyoldgit/IRremoteESP8266/issues/638#issue-421064165
@@ -588,23 +588,25 @@ TEST(TestSharpAcClass, ReconstructKnownState) {
uint8_t on_auto_auto[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x11, 0x20, 0x00, 0x08, 0x80, 0x00, 0xE0,
0x01};
- ac.on();
- ac.setMode(kSharpAcAuto);
+ ac.setPower(true, false);
ac.setTemp(kSharpAcMinTemp);
ac.setFan(kSharpAcFanAuto);
+ ac.setMode(kSharpAcAuto);
EXPECT_STATE_EQ(on_auto_auto, ac.getRaw(), kSharpAcBits);
- EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto)",
+ EXPECT_EQ("Power: On, Previous Power: Off, Mode: 0 (Auto), Temp: 15C, "
+ "Fan: 2 (Auto)",
ac.toString());
uint8_t cool_auto_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x22, 0x00, 0x08, 0x80, 0x04, 0xE0,
0x51};
ac.stateReset();
- ac.on();
+ ac.setPower(true, true);
ac.setMode(kSharpAcCool);
- ac.setTemp(28);
ac.setFan(kSharpAcFanAuto);
- EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto)",
+ ac.setTemp(28);
+ EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, "
+ "Fan: 2 (Auto)",
ac.toString());
EXPECT_STATE_EQ(cool_auto_28, ac.getRaw(), kSharpAcBits);
}
@@ -619,49 +621,56 @@ TEST(TestSharpAcClass, KnownStates) {
0x31};
ASSERT_TRUE(ac.validChecksum(off_auto_auto));
ac.setRaw(off_auto_auto);
- EXPECT_EQ("Power: Off, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto)",
+ EXPECT_EQ("Power: Off, Previous Power: On, Mode: 0 (Auto), Temp: 15C, "
+ "Fan: 2 (Auto)",
ac.toString());
uint8_t on_auto_auto[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x11, 0x20, 0x00, 0x08, 0x80, 0x00, 0xE0,
0x01};
ASSERT_TRUE(ac.validChecksum(on_auto_auto));
ac.setRaw(on_auto_auto);
- EXPECT_EQ("Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto)",
+ EXPECT_EQ("Power: On, Previous Power: Off, Mode: 0 (Auto), Temp: 15C, "
+ "Fan: 2 (Auto)",
ac.toString());
uint8_t cool_auto_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x22, 0x00, 0x08, 0x80, 0x04, 0xE0,
0x51};
ASSERT_TRUE(ac.validChecksum(cool_auto_28));
ac.setRaw(cool_auto_28);
- EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto)",
+ EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, "
+ "Fan: 2 (Auto)",
ac.toString());
uint8_t cool_fan1_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x42, 0x00, 0x08, 0x80, 0x05, 0xE0,
0x21};
ASSERT_TRUE(ac.validChecksum(cool_fan1_28));
ac.setRaw(cool_fan1_28);
- EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 4 (Low)",
+ EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, "
+ "Fan: 4 (Low)",
ac.toString());
uint8_t cool_fan2_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x32, 0x00, 0x08, 0x80, 0x05, 0xE0,
0x51};
ASSERT_TRUE(ac.validChecksum(cool_fan2_28));
ac.setRaw(cool_fan2_28);
- EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium)",
+ EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, "
+ "Fan: 3 (Medium)",
ac.toString());
uint8_t cool_fan3_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x52, 0x00, 0x08, 0x80, 0x05, 0xE0,
0x31};
ASSERT_TRUE(ac.validChecksum(cool_fan3_28));
ac.setRaw(cool_fan3_28);
- EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 5 (UNKNOWN)",
+ EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, "
+ "Fan: 5 (UNKNOWN)",
ac.toString());
uint8_t cool_fan4_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x72, 0x00, 0x08, 0x80, 0x05, 0xE0,
0x11};
ASSERT_TRUE(ac.validChecksum(cool_fan4_28));
ac.setRaw(cool_fan4_28);
- EXPECT_EQ("Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 7 (High)",
+ EXPECT_EQ("Power: On, Previous Power: On, Mode: 2 (Cool), Temp: 28C, "
+ "Fan: 7 (High)",
ac.toString());
/* Unsupported / Not yet reverse engineered.
uint8_t cool_fan4_28_ion_on[kSharpAcStateLength] = {
@@ -683,7 +692,8 @@ TEST(TestSharpAcClass, KnownStates) {
0x11};
ASSERT_TRUE(ac.validChecksum(dry_auto));
ac.setRaw(dry_auto);
- EXPECT_EQ("Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto)",
+ EXPECT_EQ("Power: On, Previous Power: On, Mode: 3 (Dry), Temp: 15C, "
+ "Fan: 2 (Auto)",
ac.toString());
}
@@ -714,3 +724,89 @@ TEST(TestSharpAcClass, toCommon) {
ASSERT_EQ(-1, ac.toCommon().sleep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
+
+TEST(TestSharpAcClass, PreviousPower) {
+ IRSharpAc ac(kGpioUnused);
+ ac.setPower(false, false);
+ EXPECT_FALSE(ac.getPower());
+ EXPECT_FALSE(ac.getPreviousPower());
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_FALSE(ac.getPreviousPower());
+ ac.setPower(false);
+ EXPECT_FALSE(ac.getPower());
+ EXPECT_TRUE(ac.getPreviousPower());
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_FALSE(ac.getPreviousPower());
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_TRUE(ac.getPreviousPower());
+ ac.setPreviousPower(false);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_FALSE(ac.getPreviousPower());
+ ac.setPreviousPower(true);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_TRUE(ac.getPreviousPower());
+ ac.setPower(true, false);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_FALSE(ac.getPreviousPower());
+
+ // Data from: https://github.com/crankyoldgit/IRremoteESP8266/pull/1074#discussion_r403407146
+ // Command ON (previously OFF) -> 0xAA 5A CF 10 CB 11 22 00 08 80 00 E0 51
+ const uint8_t on_prev_off[] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xCB, 0x11, 0x22,
+ 0x00, 0x08, 0x80, 0x00, 0xE0, 0x51};
+ ac.setRaw(on_prev_off);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_FALSE(ac.getPreviousPower());
+ // Command ON (previously ON) -> 0xAA 5A CF 10 CB 31 22 00 08 80 04 E0 31
+ const uint8_t on_prev_on[] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xCB, 0x31, 0x22,
+ 0x00, 0x08, 0x80, 0x04, 0xE0, 0x31};
+ ac.setRaw(on_prev_on);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_TRUE(ac.getPreviousPower());
+ // Command OFF (previously ON) -> 0xAA 5A CF 10 CB 21 22 00 08 80 00 E0 61
+ const uint8_t off_prev_on[] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xCB, 0x21, 0x22,
+ 0x00, 0x08, 0x80, 0x00, 0xE0, 0x61};
+ ac.setRaw(off_prev_on);
+ EXPECT_FALSE(ac.getPower());
+ EXPECT_TRUE(ac.getPreviousPower());
+ /* Extra test data if needed.
+ // Power:OFF Mode:2(Cool) Fan:2(Auto) Temp:22
+ const uint8_t collect1[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xC7, 0x21, 0x22,
+ 0x00, 0x08, 0x80, 0x00, 0xE0, 0xA1};
+ // Power:ON Mode:2(Cool) Fan:2(Auto) Temp:22
+ const uint8_t collect2[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xC7, 0x11, 0x22,
+ 0x00, 0x08, 0x80, 0x00, 0xE0, 0x91};
+ // Power:ON Mode:2(Cool) Fan:2(Auto) Temp:23
+ const uint8_t collect3[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xC8, 0x31, 0x22,
+ 0x00, 0x08, 0x80, 0x04, 0xE0, 0x01};
+ // Power:ON Mode:2(Cool) Fan:2(Auto) Temp:22
+ const uint8_t collect4[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xC7, 0x31, 0x22,
+ 0x00, 0x08, 0x80, 0x04, 0xE0, 0xF1};
+ // Power:ON Mode:3(Dry) Fan:Automaticly 2(Auto)
+ // Temp:Automaticly 15
+ const uint8_t collect5[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x31, 0x23,
+ 0x00, 0x08, 0x80, 0x00, 0xE0, 0x11};
+ // Power:ON Mode:2(Cool) Fan:2(Auto) Temp:22
+ const uint8_t collect6[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xC7, 0x31, 0x22,
+ 0x00, 0x08, 0x80, 0x00, 0xE0, 0xB1};
+ // Power:ON Mode:2(Cool) Fan:3(Medium) Temp:22
+ const uint8_t collect7[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xC7, 0x31, 0x32,
+ 0x00, 0x08, 0x80, 0x05, 0xE0, 0xF1};
+ // Power:OFF Mode:2(Cool) Fan:3(Medium) Temp:22
+ const uint8_t collect8[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xC7, 0x21, 0x32,
+ 0x00, 0x08, 0x80, 0x00, 0xE0, 0xB1};
+ */
+}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Sherwood_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Sherwood_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Sherwood_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Sherwood_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Sony_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Sony_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Sony_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Sony_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.5/test/ir_Symphony_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Symphony_test.cpp
new file mode 100644
index 000000000..ee4aadfda
--- /dev/null
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Symphony_test.cpp
@@ -0,0 +1,157 @@
+// Copyright 2020 David Conran
+
+#include "IRac.h"
+#include "IRrecv.h"
+#include "IRrecv_test.h"
+#include "IRsend.h"
+#include "IRsend_test.h"
+#include "gtest/gtest.h"
+
+// Tests for sendSymphony().
+
+// Test sending typical data only.
+TEST(TestSendSymphony, SendDataOnly) {
+ IRsendTest irsend(kGpioUnused);
+ irsend.begin();
+ irsend.sendSymphony(0x137);
+ EXPECT_EQ(
+ "f38000d50"
+ "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400"
+ "m400s1250m400s1250m400s1250"
+ "m400s8000"
+ "m1250s400m1250s400m400s1250m1250s400m1250s400m400s1250m400s1250m1250s400"
+ "m400s1250m400s1250m400s1250"
+ "m400s8000",
+ irsend.outputStr());
+}
+
+// Tests for decodeSymphony().
+
+// Decode normal Symphony messages.
+TEST(TestDecodeSymphony, SyntheticSelfDecode) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ // Real-life Symphony code from an actual capture/decode.
+ irsend.reset();
+ irsend.sendSymphony(0x123);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
+ EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
+ EXPECT_EQ(0x123, irsend.capture.value);
+ EXPECT_EQ(0, irsend.capture.address);
+ EXPECT_EQ(0, irsend.capture.command);
+ EXPECT_FALSE(irsend.capture.repeat);
+}
+
+// Decode a real Symphony message.
+TEST(TestDecodeSymphony, RealMessageDecode) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ // Real-life Symphony code from an actual capture/decode.
+ // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1057#issue-577216614
+ irsend.reset();
+ const uint16_t button_1[95] = {
+ 1296, 412, 1294, 386, 420, 1224, 1322, 390, 1290, 390, 420, 1224, 452,
+ 1220, 1314, 394, 420, 1222, 482, 1190, 480, 1192, 452, 7960,
+ 1290, 420, 1290, 390, 418, 1226, 1318, 394, 1262, 416, 420, 1224, 454,
+ 1220, 1292, 416, 422, 1222, 450, 1222, 452, 1218, 454, 8208,
+ 1296, 414, 1292, 386, 418, 1226, 1292, 422, 1260, 420, 424, 1218, 454,
+ 1226, 1312, 390, 420, 1224, 454, 1220, 482, 1186, 454, 7960,
+ 1318, 392, 1264, 416, 392, 1252, 1318, 394, 1288, 394, 418, 1224, 452,
+ 1224, 1292, 422, 414, 1222, 458, 1214, 450, 1222, 454};
+ irsend.sendRaw(button_1, 95, 38000);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
+ EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
+ EXPECT_EQ(0x137, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+ EXPECT_FALSE(irsend.capture.repeat);
+
+ // Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1057#issuecomment-596038442
+ irsend.reset();
+ const uint16_t power[23] = {
+ 1308, 368, 1310, 368, 448, 1222, 1310, 372, 1308, 400, 442, 1198, 472,
+ 1198, 1284, 396, 444, 1224, 470, 1200, 470, 1198, 472};
+ irsend.sendRaw(power, 23, 38000);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
+ EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
+ EXPECT_EQ(0x137, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+ EXPECT_FALSE(irsend.capture.repeat);
+
+ irsend.reset();
+ const uint16_t swing[23] = {
+ 1290, 418, 1286, 392, 422, 1248, 1284, 400, 1294, 386, 422, 1248, 422,
+ 1250, 444, 1228, 424, 1248, 446, 1226, 1258, 420, 446};
+ irsend.sendRaw(swing, 23, 38000);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
+ EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
+ EXPECT_EQ(0x13E, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+ EXPECT_FALSE(irsend.capture.repeat);
+}
+
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1057#issuecomment-596543641
+TEST(TestDecodeSymphony, RealMessageSentViaLibrary) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+
+ irsend.reset();
+ // Generated by the library/ESP8266.
+ const uint16_t rawdata_lib[47] = {
+ 1222, 430, 1250, 436, 410, 1242, 1274, 446, 1274, 412, 414, 1266, 410,
+ 1264, 1252, 436, 436, 1240, 410, 1270, 438, 1242, 410, 8012, 1254, 434,
+ 1258, 432, 438, 1240, 1276, 416, 1252, 434, 438, 1234, 412, 1270, 1250,
+ 442, 412, 1264, 438, 1238, 410, 1270, 438};
+ irsend.sendRaw(rawdata_lib, 47, 38000);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
+ EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
+ EXPECT_EQ(0x137, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+ EXPECT_FALSE(irsend.capture.repeat);
+
+ irsend.reset();
+ // Generated by the real remote.
+ const uint16_t rawdata_remote[47] = {
+ 1286, 396, 1286, 396, 446, 1226, 1288, 400, 1294, 388, 444, 1228, 446,
+ 1226, 1286, 396, 444, 1226, 448, 1226, 468, 1204, 448, 7968, 1286, 396,
+ 1286, 396, 470, 1202, 1286, 400, 1286, 396, 446, 1224, 448, 1226, 1288,
+ 396, 446, 1226, 472, 1200, 448, 1226, 472};
+ irsend.sendRaw(rawdata_remote, 47, 38000);
+ irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::SYMPHONY, irsend.capture.decode_type);
+ EXPECT_EQ(kSymphonyBits, irsend.capture.bits);
+ EXPECT_EQ(0x137, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+ EXPECT_FALSE(irsend.capture.repeat);
+}
+
+
+TEST(TestUtils, Housekeeping) {
+ ASSERT_EQ("SYMPHONY", typeToString(decode_type_t::SYMPHONY));
+ ASSERT_EQ(decode_type_t::SYMPHONY, strToDecodeType("SYMPHONY"));
+ ASSERT_FALSE(hasACState(decode_type_t::SYMPHONY));
+ ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::SYMPHONY));
+ ASSERT_EQ(kSymphonyBits, IRsendTest::defaultBits(decode_type_t::SYMPHONY));
+ ASSERT_EQ(kSymphonyDefaultRepeat,
+ IRsendTest::minRepeats(decode_type_t::SYMPHONY));
+}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Tcl_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Tcl_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Tcl_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Tcl_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Teco_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Teco_test.cpp
similarity index 98%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Teco_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Teco_test.cpp
index 635e93a44..f4196c3ae 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Teco_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Teco_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2019 David Conran
#include "ir_Teco.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -387,7 +388,6 @@ TEST(TestDecodeTeco, NormalDecodeWithStrict) {
TEST(TestDecodeTeco, RealNormalExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
- IRTecoAc ac(0);
irsend.begin();
uint16_t rawData1[73] = {
@@ -408,12 +408,12 @@ TEST(TestDecodeTeco, RealNormalExample) {
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, Light: Off, Humid: Off, Save: Off, Timer: Off",
- ac.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
uint16_t rawData2[73] = {
9048, 4472, 636, 548, 636, 1654, 638, 546, 642, 1650, 642, 546, 638,
@@ -433,12 +433,11 @@ TEST(TestDecodeTeco, RealNormalExample) {
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 (Medium), Sleep: Off, "
"Swing: On, Light: Off, Humid: Off, Save: Off, Timer: Off",
- ac.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Toshiba_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Toshiba_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Toshiba_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Toshiba_test.cpp
index 66c258ae4..e0ae82987 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Toshiba_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Toshiba_test.cpp
@@ -1,5 +1,6 @@
// Copyright 2017 David Conran
#include "ir_Toshiba.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -499,6 +500,11 @@ TEST(TestDecodeToshibaAC, SyntheticExample) {
ASSERT_EQ(TOSHIBA_AC, irsend.capture.decode_type);
ASSERT_EQ(kToshibaACBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
+ EXPECT_EQ(
+ "Power: On, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto)",
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
// Test decoding against captures from a real Toshiba A/C remote.
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Trotec_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Trotec_test.cpp
similarity index 95%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Trotec_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Trotec_test.cpp
index 43cb3fc06..4e8d639fe 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Trotec_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Trotec_test.cpp
@@ -1,5 +1,6 @@
// Copyright 2019 David Conran
#include "ir_Trotec.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -97,11 +98,11 @@ TEST(TestDecodeTrotec, SyntheticDecode) {
EXPECT_EQ(decode_type_t::TROTEC, irsend.capture.decode_type);
EXPECT_EQ(kTrotecBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
- IRTrotecESP ac(0);
- ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 2 (Medium), Sleep: On",
- ac.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
@@ -176,4 +177,5 @@ TEST(TestUtils, Housekeeping) {
ASSERT_EQ("TROTEC", typeToString(decode_type_t::TROTEC));
ASSERT_EQ(decode_type_t::TROTEC, strToDecodeType("TROTEC"));
ASSERT_TRUE(hasACState(decode_type_t::TROTEC));
+ ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::TROTEC));
}
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Vestel_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Vestel_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Vestel_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Vestel_test.cpp
index d20a882a6..d3f1febf8 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Vestel_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Vestel_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2019 David Conran
#include "ir_Vestel.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -441,7 +442,6 @@ TEST(TestDecodeVestelAc, NormalDecodeWithStrict) {
TEST(TestDecodeVestelAc, RealNormalExample) {
IRsendTest irsend(0);
IRrecv irrecv(0);
- IRVestelAc ac(0);
irsend.begin();
uint16_t rawData[115] = {
@@ -465,12 +465,12 @@ TEST(TestDecodeVestelAc, RealNormalExample) {
EXPECT_EQ(0xF4410001FF1201ULL, 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: 4 (Heat), Temp: 16C, Fan: 1 (Auto), Sleep: Off, "
"Turbo: Off, Ion: On, Swing: Off",
- ac.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestDecodeVestelAc, RealTimerExample) {
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Whirlpool_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Whirlpool_test.cpp
similarity index 99%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Whirlpool_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Whirlpool_test.cpp
index 901318326..a6374a7f6 100644
--- a/lib/IRremoteESP8266-2.7.4/test/ir_Whirlpool_test.cpp
+++ b/lib/IRremoteESP8266-2.7.5/test/ir_Whirlpool_test.cpp
@@ -1,6 +1,7 @@
// Copyright 2018 David Conran
#include "ir_Whirlpool.h"
+#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
#include "IRsend.h"
@@ -66,13 +67,13 @@ TEST(TestDecodeWhirlpoolAC, SyntheticDecode) {
EXPECT_EQ(WHIRLPOOL_AC, irsend.capture.decode_type);
EXPECT_EQ(kWhirlpoolAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
- IRWhirlpoolAc ac(0);
- ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Model: 1 (DG11J13A), Power Toggle: Off, Mode: 1 (Auto), Temp: 25C, "
"Fan: 0 (Auto), Swing: Off, Light: On, Clock: 17:31, On Timer: Off, "
"Off Timer: Off, Sleep: Off, Super: Off, Command: 2 (Temp)",
- ac.toString());
+ IRAcUtils::resultAcToString(&irsend.capture));
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
}
TEST(TestDecodeWhirlpoolAC, Real26CFanAutoCoolingSwingOnClock1918) {
diff --git a/lib/IRremoteESP8266-2.7.4/test/ir_Whynter_test.cpp b/lib/IRremoteESP8266-2.7.5/test/ir_Whynter_test.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/test/ir_Whynter_test.cpp
rename to lib/IRremoteESP8266-2.7.5/test/ir_Whynter_test.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/tools/Makefile b/lib/IRremoteESP8266-2.7.5/tools/Makefile
similarity index 96%
rename from lib/IRremoteESP8266-2.7.4/tools/Makefile
rename to lib/IRremoteESP8266-2.7.5/tools/Makefile
index 0ee8cc563..cfbf2e33c 100644
--- a/lib/IRremoteESP8266-2.7.4/tools/Makefile
+++ b/lib/IRremoteESP8266-2.7.5/tools/Makefile
@@ -51,7 +51,8 @@ PROTOCOLS = ir_NEC.o ir_Sony.o ir_Samsung.o ir_JVC.o ir_RCMM.o ir_RC5_RC6.o \
ir_GICable.o ir_Whirlpool.o ir_Lutron.o ir_Electra.o ir_Pioneer.o \
ir_MWM.o ir_Vestel.o ir_Teco.o ir_Tcl.o ir_Lego.o \
ir_MitsubishiHeavy.o ir_Goodweather.o ir_Inax.o ir_Argo.o \
- ir_Trotec.o ir_Neoclima.o ir_Amcor.o ir_Epson.o
+ ir_Trotec.o ir_Neoclima.o ir_Amcor.o ir_Epson.o ir_Symphony.o \
+ ir_Airwell.o
# Common object files
COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o IRtext.o IRac.o $(PROTOCOLS)
@@ -237,5 +238,11 @@ ir_Amcor.o : $(USER_DIR)/ir_Amcor.cpp $(USER_DIR)/ir_Amcor.h $(GTEST_HEADERS)
ir_Epson.o : $(USER_DIR)/ir_Epson.cpp $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Epson.cpp
+ir_Symphony.o : $(USER_DIR)/ir_Symphony.cpp $(GTEST_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Symphony.cpp
+
+ir_Airwell.o : $(USER_DIR)/ir_Airwell.cpp $(GTEST_HEADERS)
+ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_Airwell.cpp
+
IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRac.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/tools/RawToGlobalCache.sh b/lib/IRremoteESP8266-2.7.5/tools/RawToGlobalCache.sh
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/tools/RawToGlobalCache.sh
rename to lib/IRremoteESP8266-2.7.5/tools/RawToGlobalCache.sh
diff --git a/lib/IRremoteESP8266-2.7.4/tools/auto_analyse_raw_data.py b/lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data.py
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/tools/auto_analyse_raw_data.py
rename to lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data.py
diff --git a/lib/IRremoteESP8266-2.7.4/tools/auto_analyse_raw_data_test.py b/lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data_test.py
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/tools/auto_analyse_raw_data_test.py
rename to lib/IRremoteESP8266-2.7.5/tools/auto_analyse_raw_data_test.py
diff --git a/lib/IRremoteESP8266-2.7.4/tools/gc_decode.cpp b/lib/IRremoteESP8266-2.7.5/tools/gc_decode.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/tools/gc_decode.cpp
rename to lib/IRremoteESP8266-2.7.5/tools/gc_decode.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/tools/generate_irtext_h.sh b/lib/IRremoteESP8266-2.7.5/tools/generate_irtext_h.sh
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/tools/generate_irtext_h.sh
rename to lib/IRremoteESP8266-2.7.5/tools/generate_irtext_h.sh
diff --git a/lib/IRremoteESP8266-2.7.4/tools/mkkeywords b/lib/IRremoteESP8266-2.7.5/tools/mkkeywords
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/tools/mkkeywords
rename to lib/IRremoteESP8266-2.7.5/tools/mkkeywords
diff --git a/lib/IRremoteESP8266-2.7.4/tools/mode2_decode.cpp b/lib/IRremoteESP8266-2.7.5/tools/mode2_decode.cpp
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/tools/mode2_decode.cpp
rename to lib/IRremoteESP8266-2.7.5/tools/mode2_decode.cpp
diff --git a/lib/IRremoteESP8266-2.7.4/tools/scrape_supported_devices.py b/lib/IRremoteESP8266-2.7.5/tools/scrape_supported_devices.py
similarity index 100%
rename from lib/IRremoteESP8266-2.7.4/tools/scrape_supported_devices.py
rename to lib/IRremoteESP8266-2.7.5/tools/scrape_supported_devices.py
diff --git a/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp b/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp
index 1fad7c0f5..212992775 100644
--- a/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp
+++ b/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp
@@ -150,9 +150,11 @@ bool TasmotaSerial::begin(long speed, int stop_bits) {
} else {
Serial.begin(speed, SERIAL_8N1);
}
+#ifdef ESP8266
if (m_hardswap) {
Serial.swap();
}
+#endif // ESP8266
} else {
// Use getCycleCount() loop to get as exact timing as possible
m_bit_time = ESP.getCpuFreqMHz() * 1000000 / speed;
diff --git a/lib/bearssl-esp8266/src/t_inner.h b/lib/bearssl-esp8266/src/t_inner.h
index a7267f0df..8dca0c09b 100644
--- a/lib/bearssl-esp8266/src/t_inner.h
+++ b/lib/bearssl-esp8266/src/t_inner.h
@@ -2584,6 +2584,9 @@ br_cpuid(uint32_t mask_eax, uint32_t mask_ebx,
#define optimistic_yield(ignored)
#endif
+#ifdef ESP32
+#define memcpy_P memcpy
+#endif
/* ==================================================================== */
diff --git a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h
index 99459b198..3fc8ea190 100644
--- a/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h
+++ b/lib/esp-epaper-29-ws-20171230-gemu-1.1/src/epd2in9.h
@@ -68,8 +68,8 @@ public:
int16_t width;
int16_t height;
- Epd();
- ~Epd();
+// Epd();
+// ~Epd();
int Init(const unsigned char* lut);
void Init(int8_t p);
void SendCommand(unsigned char command);
diff --git a/libesp32/ESP32-to-ESP8266-compat/README.adoc b/libesp32/ESP32-to-ESP8266-compat/README.adoc
new file mode 100644
index 000000000..abf17a277
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/README.adoc
@@ -0,0 +1,19 @@
+Library for ESP32 with Tasmota
+
+This Class is for compatibility with esp8266 code
+
+== License ==
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/libesp32/ESP32-to-ESP8266-compat/keywords.txt b/libesp32/ESP32-to-ESP8266-compat/keywords.txt
new file mode 100644
index 000000000..3422d1305
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/keywords.txt
@@ -0,0 +1,24 @@
+#######################################
+# Syntax Coloring Map For Test
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+A4988_ESP32Compat KEYWORD1 A4988_ESP32Compat
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+doMove KEYWORD2
+doRotate KEYWORD2
+setRPM KEYWORD2
+setSPR KEYWORD2
+setMIS KEYWORD2
+version KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
diff --git a/libesp32/ESP32-to-ESP8266-compat/library.properties b/libesp32/ESP32-to-ESP8266-compat/library.properties
new file mode 100644
index 000000000..5d5e39166
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/library.properties
@@ -0,0 +1,9 @@
+name=ESP32-to-ESP8266-compat
+version=0.0.2
+author=Jörg Schüler-Maroldt
+maintainer=Jörg Schüler-Maroldt
+sentence=Allows Tasmota to compile for esp32
+paragraph=Allows Tasmota to compile for esp32
+category=ESP32
+url=
+architectures=*
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/AddrList.h b/libesp32/ESP32-to-ESP8266-compat/src/AddrList.h
new file mode 100644
index 000000000..cc32ea232
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/AddrList.h
@@ -0,0 +1,233 @@
+/*
+ AddrList.h - cycle through lwIP netif's ip addresses like a c++ list
+ Copyright (c) 2018 david gauchard. All right reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ This class allows to explore all configured IP addresses
+ in lwIP netifs, with that kind of c++ loop:
+
+ for (auto a: addrList)
+ out.printf("IF='%s' index=%d legacy=%d IPv4=%d local=%d hostname='%s' addr= %s\n",
+ a.iface().c_str(),
+ a.ifnumber(),
+ a.addr().isLegacy(),
+ a.addr().isV4(),
+ a.addr().isLocal(),
+ a.hostname().c_str(),
+ a.addr().toString().c_str());
+
+ This loop:
+
+ while (WiFi.status() != WL_CONNECTED()) {
+ Serial.print('.');
+ delay(500);
+ }
+
+ can be replaced by:
+
+ for (bool configured = false; !configured; ) {
+ for (auto iface: addrList)
+ if ((configured = !iface.addr().isLocal())
+ break;
+ Serial.print('.');
+ delay(500);
+ }
+
+ waiting for an IPv6 global address:
+
+ for (bool configured = false; !configured; ) {
+ for (auto iface: addrList)
+ if ((configured = ( !iface.addr().isV4()
+ && !iface.addr().isLocal())))
+ break;
+ Serial.print('.');
+ delay(500);
+ }
+
+ waiting for an IPv6 global address, on a specific interface:
+
+ for (bool configured = false; !configured; ) {
+ for (auto iface: addrList)
+ if ((configured = ( !iface.addr().isV4()
+ && !iface.addr().isLocal()
+ && iface.ifnumber() == STATION_IF)))
+ break;
+ Serial.print('.');
+ delay(500);
+ }
+*/
+
+#ifndef __ADDRLIST_H
+#define __ADDRLIST_H
+
+#include
+#include
+
+#if LWIP_IPV6
+#define IF_NUM_ADDRESSES (1 + LWIP_IPV6_NUM_ADDRESSES)
+#else
+#define IF_NUM_ADDRESSES (1)
+#endif
+
+
+namespace esp8266
+{
+
+namespace AddressListImplementation
+{
+
+
+struct netifWrapper
+{
+ netifWrapper (netif* netif) : _netif(netif), _num(-1) {}
+ netifWrapper (const netifWrapper& o) : _netif(o._netif), _num(o._num) {}
+
+ netifWrapper& operator= (const netifWrapper& o)
+ {
+ _netif = o._netif;
+ _num = o._num;
+ return *this;
+ }
+
+ bool equal(const netifWrapper& o)
+ {
+ return _netif == o._netif && (!_netif || _num == o._num);
+ }
+
+ // address properties
+ class IPAddress4 : public IPAddress
+ {
+ public:
+ bool isV6() const
+ {
+ return false;
+ }
+ bool isLocal() const
+ {
+ return false;
+ }
+ };
+ IPAddress4 addr () const { return ipFromNetifNum(); }
+ bool isLegacy () const { return _num == 0; }
+ //bool isLocal () const { return addr().isLocal(); }
+ bool isV4 () const { return addr().isV4(); }
+ bool isV6 () const { return !addr().isV4(); }
+ String toString() const { return addr().toString(); }
+
+ // related to legacy address (_num=0, ipv4)
+ IPAddress ipv4 () const { return _netif->ip_addr; }
+ IPAddress netmask () const { return _netif->netmask; }
+ IPAddress gw () const { return _netif->gw; }
+
+ // common to all addresses of this interface
+ String ifname () const { return String(_netif->name[0]) + _netif->name[1]; }
+ const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); }
+ const char* ifmac () const { return (const char*)_netif->hwaddr; }
+ int ifnumber () const { return _netif->num; }
+ bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); }
+ const netif* interface () const { return _netif; }
+
+ const ip_addr_t* ipFromNetifNum () const
+ {
+#if LWIP_IPV6
+ return _num ? &_netif->ip6_addr[_num - 1] : &_netif->ip_addr;
+#else
+ return &_netif->ip_addr;
+#endif
+ }
+
+ // lwIP interface
+ netif* _netif;
+
+ // address index within interface
+ // 0: legacy address (IPv4)
+ // n>0: (_num-1) is IPv6 index for netif->ip6_addr[]
+ int _num;
+};
+
+
+class AddressListIterator
+{
+public:
+ AddressListIterator (const netifWrapper& o) : netIf(o) {}
+ AddressListIterator (netif* netif) : netIf(netif)
+ {
+ // This constructor is called with lwIP's global netif_list, or
+ // nullptr. operator++() is designed to loop through _configured_
+ // addresses. That's why netIf's _num is initialized to -1 to allow
+ // returning the first usable address to AddressList::begin().
+ (void)operator++();
+ }
+
+ const netifWrapper& operator* () const { return netIf; }
+ const netifWrapper* operator-> () const { return &netIf; }
+
+ bool operator== (AddressListIterator& o) { return netIf.equal(*o); }
+ bool operator!= (AddressListIterator& o) { return !netIf.equal(*o); }
+
+ AddressListIterator operator++ (int)
+ {
+ AddressListIterator ret = *this;
+ (void)operator++();
+ return ret;
+ }
+
+ AddressListIterator& operator++ ()
+ {
+ while (netIf._netif)
+ {
+ if (++netIf._num == IF_NUM_ADDRESSES)
+ {
+ // all addresses from current interface were iterated,
+ // switching to next interface
+ netIf = netifWrapper(netIf._netif->next);
+ continue;
+ }
+ if (!ip_addr_isany(netIf.ipFromNetifNum()))
+ // found an initialized address
+ break;
+ }
+ return *this;
+ }
+
+ netifWrapper netIf;
+};
+
+
+class AddressList
+{
+public:
+ using const_iterator = const AddressListIterator;
+
+ const_iterator begin () const { return const_iterator(netif_list); }
+ const_iterator end () const { return const_iterator(nullptr); }
+
+};
+
+inline AddressList::const_iterator begin (const AddressList& a) { return a.begin(); }
+inline AddressList::const_iterator end (const AddressList& a) { return a.end(); }
+
+
+} // AddressListImplementation
+
+} // esp8266
+
+extern AddressList addrList;
+
+
+#endif
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp b/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp
new file mode 100644
index 000000000..9ce191cde
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp
@@ -0,0 +1,93 @@
+/*
+ WiFi compat with ESP32
+
+ Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+//
+#include "Arduino.h"
+#include
+
+//
+// Wifi
+//
+#ifdef WiFi
+#undef WiFi
+#endif
+
+void WiFiClass32::setSleepMode(int iSleepMode)
+{
+ // WIFI_MODEM_SLEEP
+ WiFi.setSleep(iSleepMode != WIFI_MODEM_SLEEP);
+}
+
+int WiFiClass32::getPhyMode()
+{
+ return 0; // " BGN"
+}
+
+void WiFiClass32::wps_disable()
+{
+}
+
+void WiFiClass32::setOutputPower(int n)
+{
+ wifi_power_t p = WIFI_POWER_2dBm;
+ if (n > 19)
+ p = WIFI_POWER_19_5dBm;
+ else if (n > 18)
+ p = WIFI_POWER_18_5dBm;
+ else if (n >= 17)
+ p = WIFI_POWER_17dBm;
+ else if (n >= 15)
+ p = WIFI_POWER_15dBm;
+ else if (n >= 13)
+ p = WIFI_POWER_13dBm;
+ else if (n >= 11)
+ p = WIFI_POWER_11dBm;
+ else if (n >= 8)
+ p = WIFI_POWER_8_5dBm;
+ else if (n >= 7)
+ p = WIFI_POWER_7dBm;
+ else if (n >= 5)
+ p = WIFI_POWER_5dBm;
+ WiFi.setTxPower(p);
+}
+
+void WiFiClass32::forceSleepBegin()
+{
+}
+
+void WiFiClass32::forceSleepWake()
+{
+}
+
+bool WiFiClass32::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel, bool &hidden_scan)
+{
+ hidden_scan = false;
+ return WiFi.getNetworkInfo(i, ssid, encType, rssi, bssid, channel);
+}
+
+void wifi_station_disconnect()
+{
+ // erase ap: empty ssid, ...
+ WiFi.disconnect(true, true);
+}
+
+void wifi_station_dhcpc_start()
+{
+}
+
+WiFiClass32 WiFi32;
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266HTTPClient.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266HTTPClient.h
new file mode 100644
index 000000000..178911e3c
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266HTTPClient.h
@@ -0,0 +1,5 @@
+//
+// Compat with ESP32
+//
+#include
+
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WebServer.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WebServer.h
new file mode 100644
index 000000000..f00be7b64
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WebServer.h
@@ -0,0 +1,19 @@
+//
+// Compat with ESP32
+//
+#pragma once
+#include
+
+//#define ESP8266WebServer WebServer
+
+
+class ESP8266WebServer : public WebServer
+{
+public:
+ ESP8266WebServer(int port)
+ :WebServer(port)
+ {
+ }
+};
+
+//#define ENC_TYPE_AUTO 0
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h
new file mode 100644
index 000000000..09d404e72
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h
@@ -0,0 +1,85 @@
+/*
+ WiFi compat with ESP32
+
+ Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+#pragma once
+#include
+
+// sorry, no
+#undef LWIP_IPV6
+
+#define ENC_TYPE_NONE WIFI_AUTH_OPEN
+#define ENC_TYPE_WEP WIFI_AUTH_WEP
+#define ENC_TYPE_CCMP WIFI_AUTH_WPA2_PSK
+#define ENC_TYPE_TKIP WIFI_AUTH_WPA_WPA2_PSK
+#define ENC_TYPE_AUTO WIFI_AUTH_MAX + 1
+
+#define WIFI_LIGHT_SLEEP 1
+#define WIFI_MODEM_SLEEP 2
+
+class WiFiClass32 : public WiFiClass
+{
+public:
+ static void hostname(const char* aHostname)
+ {
+ WiFi.setHostname(aHostname);
+ }
+ static void setSleepMode(int iSleepMode);
+ static int getPhyMode();
+
+ static void wps_disable();
+ static void setOutputPower(int n);
+ static void forceSleepBegin();
+ static void forceSleepWake();
+ static bool getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &hidden_scan);
+};
+
+void wifi_station_disconnect();
+void wifi_station_dhcpc_start();
+extern WiFiClass32 WiFi32;
+#define WiFi WiFi32
+
+class WiFiUDP32 : public WiFiUDP
+{
+ public:
+ size_t write(const char*s)
+ {
+ return WiFiUDP::write((const uint8_t *)s, strlen(s));
+ }
+ size_t write(const uint8_t *buf, size_t n)
+ {
+ return WiFiUDP::write(buf, n);
+ }
+ static void stopAll()
+ {
+
+ }
+ static void forceSleepWake()
+ {
+
+ }
+ uint8_t beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port)
+ {
+ return WiFiUDP::beginMulticast(multicast, port);
+ }
+ void beginPacketMulticast(IPAddress multicast, uint16_t port, IPAddress interfaceAddr)
+ {
+
+ }
+};
+
+#define WiFiUDP WiFiUDP32
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266httpUpdate.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266httpUpdate.h
new file mode 100644
index 000000000..0ef8fbbb0
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266httpUpdate.h
@@ -0,0 +1,10 @@
+//
+// Compat with ESP32
+//
+#include
+#define ESPhttpUpdate httpUpdate
+
+inline HTTPUpdateResult ESPhttpUpdate_update(const String& url, const String& currentVersion = "")
+{
+ return HTTP_UPDATE_OK;
+}
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ESP8266mDNS.h b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266mDNS.h
new file mode 100644
index 000000000..f679ec5fa
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/ESP8266mDNS.h
@@ -0,0 +1,4 @@
+//
+// Compat with ESP32
+//
+#include
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/c_types.h b/libesp32/ESP32-to-ESP8266-compat/src/c_types.h
new file mode 100644
index 000000000..22f551391
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/c_types.h
@@ -0,0 +1,6 @@
+#pragma once
+/**/
+#include
+#ifndef ICACHE_FLASH_ATTR
+#define ICACHE_FLASH_ATTR
+#endif
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/eboot_command.h b/libesp32/ESP32-to-ESP8266-compat/src/eboot_command.h
new file mode 100644
index 000000000..992d014ea
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/eboot_command.h
@@ -0,0 +1,3 @@
+//
+// Compat with ESP32
+//
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp
new file mode 100644
index 000000000..0490991c4
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.cpp
@@ -0,0 +1,73 @@
+/*
+ This library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ */
+//
+#include "Arduino.h"
+#include "lwip/apps/sntp.h"
+#include
+#include
+#include
+#include "esp8266toEsp32.h"
+// ESP Stuff
+struct rst_info resetInfo;
+
+String ESP_getResetReason(void)
+{
+ // CPU 0
+ return String(rtc_get_reset_reason(0));
+}
+
+String ESP_getResetInfo(void)
+{
+ return String(PSTR("0"));
+}
+
+String ESP_getBootVersion(void)
+{
+ return String(PSTR("Unknown"));
+}
+
+bool ESP_rtcUserMemoryWrite(uint32_t offset, uint32_t *data, size_t size)
+{
+ return false;
+}
+
+bool ESP_rtcUserMemoryRead(uint32_t offset, uint32_t *data, size_t size)
+{
+ return false;
+}
+
+void ESP_reset()
+{
+ ESP.restart();
+}
+
+uint32_t ESP_getFlashChipId()
+{
+ return 0;
+}
+
+String String_ESP_getChipId()
+{
+ uint64_t mac = ESP.getEfuseMac();
+ return String(uint32_t(mac >> 32)) + String(uint32_t(mac));
+}
+
+/*
+uint64_t ESP_getChipId()
+{
+ return ESP.getEfuseMac();
+}
+*/
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h
new file mode 100644
index 000000000..1071bfbd1
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h
@@ -0,0 +1,115 @@
+/*
+ This library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ */
+#pragma once
+#ifdef ESP32
+// my debug Stuff
+#define Serial_Debug1(p) Serial.printf p
+#define Serial_DebugX(p)
+
+//
+// basics
+//
+// dummy defines
+#define SPIFFS_END (SPI_FLASH_SEC_SIZE * 200)
+#define SETTINGS_LOCATION SPIFFS_END
+
+#include
+
+//
+// ESP32
+//
+#define ESP_flashReadHeader(offset, data, size) ESP32_flashRead(offset, data, size)
+#define ESP_flashRead(offset, data, size) ESP32_flashRead(offset, data, size)
+String ESP_getResetReason(void);
+String ESP_getBootVersion(void);
+bool ESP_rtcUserMemoryWrite(uint32_t offset, uint32_t *data, size_t size);
+bool ESP_rtcUserMemoryRead(uint32_t offset, uint32_t *data, size_t size);
+void ESP_reset();
+String ESP_getResetInfo(void);
+uint32_t ESP_getFlashChipId();
+String String_ESP_getChipId();
+
+// Analog
+inline void analogWrite(uint8_t pin, int val)
+{
+}
+
+inline void analogWriteFreq(uint32_t freq)
+{
+}
+inline void analogWriteRange(uint32_t range)
+{
+}
+
+#define INPUT_PULLDOWN_16 INPUT_PULLUP
+
+typedef double real64_t;
+
+//
+// Time and Timer
+//
+#define ETS_UART_INTR_DISABLE()
+#define ETS_UART_INTR_ENABLE()
+
+#define getChipId() getEfuseMac()
+#define ESPhttpUpdate httpUpdate
+#define getFlashChipRealSize() getFlashChipSize()
+
+#define os_delay_us ets_delay_us
+// Serial minimal type to hold the config
+typedef int SerConfu8;
+typedef int SerialConfig;
+#define analogWrite(a, b)
+
+//
+// WS2812
+//
+#define NeoEsp8266BitBang800KbpsMethod NeoEsp32BitBang800KbpsMethod
+//
+// UDP
+//
+//#define PortUdp_writestr(log_data) PortUdp.write((const uint8_t *)(log_data), strlen(log_data))
+#define PortUdp_write(log_data, n) PortUdp.write((const uint8_t *)(log_data), n)
+
+//
+#define wifi_forceSleepBegin()
+
+#undef LWIP_IPV6
+
+struct rst_info
+{
+ int reason;
+};
+
+#define REASON_DEFAULT_RST 1
+#define REASON_EXT_SYS_RST 2
+#define REASON_DEEP_SLEEP_AWAKE 3
+
+// memmove ...
+#define memcpy_P memcpy
+#define memmove_P memmove
+#define strncpy_P strncpy
+#define strcmp_P strcmp
+#define memccpy_P memccpy
+#define snprintf_P snprintf
+#define sprintf_P sprintf
+#define strncmp_P strncmp
+
+// LWIP STuff
+
+#define STATION_IF 0
+
+#endif
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/ets_sys.h b/libesp32/ESP32-to-ESP8266-compat/src/ets_sys.h
new file mode 100644
index 000000000..30a7e7733
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/ets_sys.h
@@ -0,0 +1,3 @@
+#pragma once
+#define timercallback void*
+#define ets_printf(...)
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/gpio.h b/libesp32/ESP32-to-ESP8266-compat/src/gpio.h
new file mode 100644
index 000000000..0ff47d6a2
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/gpio.h
@@ -0,0 +1,2 @@
+#pragma once
+#define GPIO_STATUS_W1TC_ADDRESS 0x24
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/os_type.h b/libesp32/ESP32-to-ESP8266-compat/src/os_type.h
new file mode 100644
index 000000000..a9e1558f5
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/os_type.h
@@ -0,0 +1,6 @@
+#pragma once
+#include "esp8266-compat.h"
+#include
+#include
+typedef uint16 uint16_t;
+typedef double real64_t;
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/osapi.h b/libesp32/ESP32-to-ESP8266-compat/src/osapi.h
new file mode 100644
index 000000000..947de57cc
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/osapi.h
@@ -0,0 +1,8 @@
+#pragma once
+/**/
+#include
+/*
+#ifndef ICACHE_FLASH_ATTR
+#define ICACHE_FLASH_ATTR
+#endif
+*/
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/sntp.h b/libesp32/ESP32-to-ESP8266-compat/src/sntp.h
new file mode 100644
index 000000000..2d92438d5
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/sntp.h
@@ -0,0 +1,7 @@
+#pragma once
+#define sntp_get_current_timestamp() SntpGetCurrentTimestamp()
+#define sntp_init() SntpInit()
+#define sntp_set_timezone(tz)
+#define sntp_setservername(idx, name)
+#define sntp_stop()
+
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/spi_flash.h b/libesp32/ESP32-to-ESP8266-compat/src/spi_flash.h
new file mode 100644
index 000000000..fffa3c3a0
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/spi_flash.h
@@ -0,0 +1,4 @@
+//
+// Compat with ESP32
+//
+// TODO: Port it to ESP32
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/twi.h b/libesp32/ESP32-to-ESP8266-compat/src/twi.h
new file mode 100644
index 000000000..eaf51d122
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/twi.h
@@ -0,0 +1,2 @@
+#pragma once
+/**/
\ No newline at end of file
diff --git a/libesp32/ESP32-to-ESP8266-compat/src/user_interface.h b/libesp32/ESP32-to-ESP8266-compat/src/user_interface.h
new file mode 100644
index 000000000..ee38dfb21
--- /dev/null
+++ b/libesp32/ESP32-to-ESP8266-compat/src/user_interface.h
@@ -0,0 +1,24 @@
+/*
+ This library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+#ifndef user_interface_h
+#define user_interface_h
+enum wps_cb_status {
+ WPS_CB_ST_SUCCESS = 0,
+ WPS_CB_ST_FAILED,
+ WPS_CB_ST_TIMEOUT,
+ WPS_CB_ST_WEP,
+ WPS_CB_ST_UNK,
+};
+#endif
diff --git a/platformio_override_esp32.ini b/platformio_override_esp32.ini
new file mode 100644
index 000000000..d2f6ae536
--- /dev/null
+++ b/platformio_override_esp32.ini
@@ -0,0 +1,109 @@
+;
+; Example PlatformIO Project Configuration Override for ESP32 ***
+; Changes done here override settings in platformio.ini ***
+;
+; to build Tasmota ESP32 copy to platformio_override.ini ***
+;
+; Please visit documentation for the options and examples
+; http://docs.platformio.org/en/stable/projectconf.html
+;
+
+
+[platformio]
+; *** Build/upload environment
+;monitor_port = COM5
+default_envs =
+; *** Uncomment the line(s) below to select version(s)
+ tasmota
+ tasmota32
+; tasmota32-minimal
+; tasmota32-lite
+; tasmota32-knx
+; tasmota32-sensors
+; tasmota32-display
+; tasmota32-ir
+; tasmota32-ircustom
+; tasmota32-DE
+; tasmota32-NL
+
+[env32]
+; uncomment this for all other tasmota32 builds
+[env:tasmota32]
+framework = ${common.framework}
+platform = ${common32.platform}
+platform_packages = ${common32.platform_packages}
+board = ${common32.board}
+board_build.ldscript = ${common32.board_build.ldscript}
+board_build.flash_mode = ${common32.board_build.flash_mode}
+board_build.f_cpu = ${common32.board_build.f_cpu}
+build_unflags = ${common32.build_unflags}
+build_flags = ${common32.build_flags}
+monitor_speed = ${common32.monitor_speed}
+upload_port = ${common32.upload_port}
+upload_resetmethod = ${common32.upload_resetmethod}
+upload_speed = ${common32.upload_speed}
+extra_scripts = ${common32.extra_scripts}
+lib_extra_dirs = ${common32.lib_extra_dirs}
+lib_ignore = ${common32.lib_ignore}
+
+; uncomment this for all other tasmota32 builds
+;[env:tasmota32]
+
+[env:tasmota32-minimal]
+build_flags = ${common.build_flags} -DFIRMWARE_MINIMAL
+[env:tasmota32-lite]
+build_flags = ${common.build_flags} -DFIRMWARE_LITE
+[env:tasmota32-knx]
+build_flags = ${common.build_flags} -DFIRMWARE_KNX_NO_EMULATION
+[env:tasmota32-sensors]
+build_flags = ${common.build_flags} -DFIRMWARE_SENSORS
+[env:tasmota32-display]
+build_flags = ${common.build_flags} -DFIRMWARE_DISPLAYS
+[env:tasmota32-ir]
+build_flags = ${common.build_flags} ${irremoteesp8266_full.build_flags} -DFIRMWARE_IR
+[env:tasmota32-ircustom]
+build_flags = ${common.build_flags} ${irremoteesp8266_full.build_flags}
+[env:tasmota32-DE]
+build_flags = ${common.build_flags} -DMY_LANGUAGE=de-DE
+[env:tasmota32-NL]
+build_flags = ${common.build_flags} -DMY_LANGUAGE=nl-NL
+
+[common32]
+platform = espressif32@1.12.0
+platform_packages =
+board = wemos_d1_mini32
+board_build.ldscript = esp32_out.ld
+board_build.flash_mode = ${common.board_build.flash_mode}
+board_build.f_cpu = ${common.board_build.f_cpu}
+build_unflags = ${common.build_unflags}
+monitor_speed = ${common.monitor_speed}
+upload_port = ${common.upload_port}
+upload_resetmethod = ${common.upload_resetmethod}
+upload_speed = 921600
+extra_scripts = ${common.extra_scripts}
+
+build_flags =
+ -D BUFFER_LENGTH=128
+ -D MQTT_MAX_PACKET_SIZE=1000
+ -D uint32=uint32_t
+ -D uint16=uint16_t
+ -D uint8=uint8_t
+ -D sint8_t=int8_t
+ -D sint32_t=int32_t
+ -D sint16_t=int16_t
+ -D memcpy_P=memcpy
+ -D memcmp_P=memcmp
+; -D USE_CONFIG_OVERRIDE
+
+lib_extra_dirs =
+ libesp32
+
+lib_ignore =
+ ESP MQTT
+ TasmotaMqtt
+ ILI9488
+ RA8876
+ SSD3115
+ cc1101
+ FrogmoreScd30
+ ArduinoNTPd
diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md
index 97de5b63f..6806dba77 100644
--- a/tasmota/CHANGELOG.md
+++ b/tasmota/CHANGELOG.md
@@ -5,17 +5,26 @@
- Change light scheme 2,3,4 cycle time speed from 24,48,72,... seconds to 4,6,12,24,36,48,... seconds (#8034)
- Change remove floating point libs from IRAM
- Change remove MQTT Info messages on restart for DeepSleep Wake (#8044)
+- Change IRremoteESP8266 library updated to v2.7.5
+- Fix PWM flickering during wifi connection (#8046)
+- Fix Zigbee crash with Occupancy sensor (#8089)
- Add support for longer template names
- Add Zigbee command ``ZbBindState`` and ``manuf``attribute
- Add commands ``CounterDebounceLow`` and ``CounterDebounceHigh`` to control debouncing (#8021)
+- Add commands ``NrfPage``, ``NrfIgnore``, ``NrfScan`` and ``NrfBeacon`` to NRF24 Bluetooth driver (#8075)
- Add command ``SetOption90 1`` to disable non-json MQTT messages (#8044)
- Add command ``Sensor10 0/1/2`` to control BH1750 resolution - 0 = High (default), 1 = High2, 2 = Low (#8016)
- Add command ``Sensor10 31..254`` to control BH1750 measurement time which defaults to 69 (#8016)
- Add command ``SetOption91 1`` to enable fading at startup / power on
- Add command ``SetOption41 `` to force sending gratuitous ARP every seconds
+- Add command ``DevGroupName`` to specify up to four Device Group Names (#8087)
+- Add command ``DevGroupSend`` to send an update to a Device Group (#8093)
+- Add command ``Ping`` (#7176)
- Add quick wifi reconnect using saved AP parameters when ``SetOption56 0`` (#3189)
-- Fix PWM flickering during wifi connection (#8046)
-- Fix Zigbee crash with Occupancy sensor (#8089)
+- Add more accuracy to GPS NTP server (#8088)
+- Add support for an iAQ sensor (#8107)
+- Add support for Seven Segment display using HT16K33 (#8116)
+- Add support for AS3935 Lightning Sensor by device111 (#8130)
### 8.2.0.2 20200328
diff --git a/tasmota/core_esp8266_timer.c b/tasmota/core_esp8266_timer.c
index bf852784c..91541d227 100644
--- a/tasmota/core_esp8266_timer.c
+++ b/tasmota/core_esp8266_timer.c
@@ -19,6 +19,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef ESP8266
+
// Use PWM from core 2.4.0 as all versions below 2.5.0-beta3 produce LED flickering when settings are saved to flash
#include
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
@@ -109,3 +111,5 @@ void ICACHE_RAM_ATTR timer0_detachInterrupt(void) {
}
#endif // ARDUINO_ESP8266_RELEASE
+
+#endif // ESP8266
diff --git a/tasmota/core_esp8266_waveform.cpp b/tasmota/core_esp8266_waveform.cpp
index a35bb7c84..1ae2d7457 100644
--- a/tasmota/core_esp8266_waveform.cpp
+++ b/tasmota/core_esp8266_waveform.cpp
@@ -37,6 +37,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef ESP8266
+
#include
#if defined(ARDUINO_ESP8266_RELEASE_2_6_1) || defined(ARDUINO_ESP8266_RELEASE_2_6_2) || defined(ARDUINO_ESP8266_RELEASE_2_6_3) || !defined(ARDUINO_ESP8266_RELEASE)
#warning **** Tasmota is using a patched PWM Arduino version as planned ****
@@ -341,4 +343,6 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
};
-#endif // ARDUINO_ESP8266_RELEASE
\ No newline at end of file
+#endif // ARDUINO_ESP8266_RELEASE
+
+#endif // ESP8266
diff --git a/tasmota/core_esp8266_wiring_digital.c b/tasmota/core_esp8266_wiring_digital.c
index 4b9ab252b..15c60503c 100644
--- a/tasmota/core_esp8266_wiring_digital.c
+++ b/tasmota/core_esp8266_wiring_digital.c
@@ -19,6 +19,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef ESP8266
+
// Use PWM from core 2.4.0 as all versions below 2.5.0-beta3 produce LED flickering when settings are saved to flash
#include
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
@@ -217,3 +219,5 @@ extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attrib
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
#endif // ARDUINO_ESP8266_RELEASE
+
+#endif // ESP8266
diff --git a/tasmota/core_esp8266_wiring_pwm.c b/tasmota/core_esp8266_wiring_pwm.c
index 8bd24815c..19e584236 100644
--- a/tasmota/core_esp8266_wiring_pwm.c
+++ b/tasmota/core_esp8266_wiring_pwm.c
@@ -19,6 +19,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#ifdef ESP8266
+
// Use PWM from core 2.4.0 as all versions below 2.5.0-beta3 produce LED flickering when settings are saved to flash
#include
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
@@ -232,3 +234,5 @@ extern void analogWriteFreq(uint32_t freq) __attribute__ ((weak, alias("__analog
extern void analogWriteRange(uint32_t range) __attribute__ ((weak, alias("__analogWriteRange")));
#endif // ARDUINO_ESP8266_RELEASE
+
+#endif // ESP8266
diff --git a/tasmota/i18n.h b/tasmota/i18n.h
index 0cbe48cf6..706482caa 100644
--- a/tasmota/i18n.h
+++ b/tasmota/i18n.h
@@ -63,6 +63,7 @@
#define D_JSON_ENERGY "Energy"
#define D_JSON_ERASE "Erase"
#define D_JSON_ERROR "Error"
+#define D_JSON_EVENT "Event"
#define D_JSON_EVERY "Every"
#define D_JSON_EXPORT_ACTIVE "ExportActive"
#define D_JSON_EXPORT_REACTIVE "ExportReactive"
@@ -535,10 +536,13 @@
#define D_PRFX_SHUTTER "Shutter"
#define D_CMND_SHUTTER_OPEN "Open"
#define D_CMND_SHUTTER_CLOSE "Close"
+#define D_CMND_SHUTTER_TOGGLE "Toggle"
#define D_CMND_SHUTTER_UP "Up"
#define D_CMND_SHUTTER_DOWN "Down"
-#define D_CMND_SHUTTER_TOGGLEUP "ToggleUp"
-#define D_CMND_SHUTTER_TOGGLEDOWN "ToggleDown"
+#define D_CMND_SHUTTER_STOPOPEN "StopOpen"
+#define D_CMND_SHUTTER_STOPCLOSE "StopClose"
+#define D_CMND_SHUTTER_STOPTOGGLE "StopToggle"
+#define D_CMND_SHUTTER_STOPPOSITION "StopPosition"
#define D_CMND_SHUTTER_STOP "Stop"
#define D_CMND_SHUTTER_POSITION "Position"
#define D_CMND_SHUTTER_OPENTIME "OpenDuration"
@@ -563,6 +567,10 @@
#define D_CMND_BRI_PRESET "BriPreset"
#endif
+// Commands xdrv_38_ping.ino
+#define D_CMND_PING "Ping"
+#define D_JSON_PING "Ping"
+
// Commands xsns_02_analog.ino
#define D_CMND_ADCPARAM "AdcParam"
diff --git a/tasmota/language/bg-BG.h b/tasmota/language/bg-BG.h
index 33bce1cc2..5a771ec11 100644
--- a/tasmota/language/bg-BG.h
+++ b/tasmota/language/bg-BG.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -675,6 +676,7 @@
#define D_UNIT_GALLONS_PER_MIN "gal/min"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
#define D_UNIT_KILOOHM "kΩ"
#define D_UNIT_KILOWATTHOUR "kWh"
diff --git a/tasmota/language/cs-CZ.h b/tasmota/language/cs-CZ.h
index fdf0c505c..de709d07e 100644
--- a/tasmota/language/cs-CZ.h
+++ b/tasmota/language/cs-CZ.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -675,6 +676,7 @@
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
#define D_UNIT_KILOWATTHOUR "kWh"
diff --git a/tasmota/language/de-DE.h b/tasmota/language/de-DE.h
index db78c327e..675ea9786 100644
--- a/tasmota/language/de-DE.h
+++ b/tasmota/language/de-DE.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/el-GR.h b/tasmota/language/el-GR.h
index 635addd81..19c0a0c56 100644
--- a/tasmota/language/el-GR.h
+++ b/tasmota/language/el-GR.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/en-GB.h b/tasmota/language/en-GB.h
index 0862c0fbe..4da4ba276 100644
--- a/tasmota/language/en-GB.h
+++ b/tasmota/language/en-GB.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/es-ES.h b/tasmota/language/es-ES.h
index 213f9dedf..e074dcf6b 100644
--- a/tasmota/language/es-ES.h
+++ b/tasmota/language/es-ES.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/fr-FR.h b/tasmota/language/fr-FR.h
index 0fa74e022..a00ef34a1 100644
--- a/tasmota/language/fr-FR.h
+++ b/tasmota/language/fr-FR.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "gal/mn"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/he-HE.h b/tasmota/language/he-HE.h
index cd56399b6..f86a0abfe 100644
--- a/tasmota/language/he-HE.h
+++ b/tasmota/language/he-HE.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/hu-HU.h b/tasmota/language/hu-HU.h
index 5cc945849..8efaf236d 100644
--- a/tasmota/language/hu-HU.h
+++ b/tasmota/language/hu-HU.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/it-IT.h b/tasmota/language/it-IT.h
index 3e94424b1..934fcfc75 100644
--- a/tasmota/language/it-IT.h
+++ b/tasmota/language/it-IT.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 - GDO2"
#define D_SENSOR_HRXL_RX "HRXL - RX"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL - TX"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/ko-KO.h b/tasmota/language/ko-KO.h
index e807569d9..75925b2d3 100644
--- a/tasmota/language/ko-KO.h
+++ b/tasmota/language/ko-KO.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/nl-NL.h b/tasmota/language/nl-NL.h
index 332ee935c..7a3ad605d 100644
--- a/tasmota/language/nl-NL.h
+++ b/tasmota/language/nl-NL.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/pl-PL.h b/tasmota/language/pl-PL.h
index ede297ffc..5dba67103 100644
--- a/tasmota/language/pl-PL.h
+++ b/tasmota/language/pl-PL.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/pt-BR.h b/tasmota/language/pt-BR.h
index d64b134aa..58bc33d91 100644
--- a/tasmota/language/pt-BR.h
+++ b/tasmota/language/pt-BR.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/pt-PT.h b/tasmota/language/pt-PT.h
index b4f336e65..e31997ecb 100644
--- a/tasmota/language/pt-PT.h
+++ b/tasmota/language/pt-PT.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/ro-RO.h b/tasmota/language/ro-RO.h
index 355dfd77b..0d29cd8dd 100644
--- a/tasmota/language/ro-RO.h
+++ b/tasmota/language/ro-RO.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/ru-RU.h b/tasmota/language/ru-RU.h
index 41e909564..12696e0bf 100644
--- a/tasmota/language/ru-RU.h
+++ b/tasmota/language/ru-RU.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "А"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "кОм"
diff --git a/tasmota/language/sk-SK.h b/tasmota/language/sk-SK.h
index 037aeaaa8..93c02cddd 100644
--- a/tasmota/language/sk-SK.h
+++ b/tasmota/language/sk-SK.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -675,6 +676,7 @@
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
#define D_UNIT_KILOWATTHOUR "kWh"
diff --git a/tasmota/language/sv-SE.h b/tasmota/language/sv-SE.h
index c52b6eaa2..9fdd52c5d 100644
--- a/tasmota/language/sv-SE.h
+++ b/tasmota/language/sv-SE.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "ink"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/tr-TR.h b/tasmota/language/tr-TR.h
index f7431cc12..2d568bf4a 100644
--- a/tasmota/language/tr-TR.h
+++ b/tasmota/language/tr-TR.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "A"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "kΩ"
diff --git a/tasmota/language/uk-UA.h b/tasmota/language/uk-UA.h
index e477b49a7..64f97093c 100644
--- a/tasmota/language/uk-UA.h
+++ b/tasmota/language/uk-UA.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "А"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "гал"
#define D_UNIT_GALLONS_PER_MIN "гал/хв"
#define D_UNIT_INCREMENTS "інк"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "кг"
#define D_UNIT_KILOMETER_PER_HOUR "км/г" // or "km/h"
#define D_UNIT_KILOOHM "㏀"
diff --git a/tasmota/language/zh-CN.h b/tasmota/language/zh-CN.h
index b4b3348a3..b98006123 100644
--- a/tasmota/language/zh-CN.h
+++ b/tasmota/language/zh-CN.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "安"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "千克"
#define D_UNIT_KILOMETER_PER_HOUR "公里/时" // or "km/h"
#define D_UNIT_KILOOHM "千欧"
diff --git a/tasmota/language/zh-TW.h b/tasmota/language/zh-TW.h
index 17267128f..d4fa149d5 100644
--- a/tasmota/language/zh-TW.h
+++ b/tasmota/language/zh-TW.h
@@ -665,6 +665,7 @@
#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2"
#define D_SENSOR_HRXL_RX "HRXL Rx"
#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx"
+#define D_SENSOR_AS3935 "AS3935"
// Units
#define D_UNIT_AMPERE "安"
@@ -674,6 +675,7 @@
#define D_UNIT_GALLONS "gal"
#define D_UNIT_GALLONS_PER_MIN "g/m"
#define D_UNIT_INCREMENTS "inc"
+#define D_UNIT_KILOMETER "km"
#define D_UNIT_KILOGRAM "kg"
#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h"
#define D_UNIT_KILOOHM "千歐"
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index 9e4be6012..660b0aabf 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -389,6 +389,9 @@
#define USE_SUNRISE // Add support for Sunrise and sunset tools (+16k)
#define SUNRISE_DAWN_ANGLE DAWN_NORMAL // Select desired Dawn Angle from (DAWN_NORMAL, DAWN_CIVIL, DAWN_NAUTIC, DAWN_ASTRONOMIC)
+// -- Ping ----------------------------------------
+// #define USE_PING // Enable Ping command (+3k code)
+
// -- Rules or Script ----------------------------
// Select none or only one of the below defines
#define USE_RULES // Add support for rules (+8k code)
@@ -499,6 +502,8 @@
// #define WEMOS_MOTOR_V1_ADDR 0x30 // Default I2C address 0x30
// #define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency
// #define USE_HDC1080 // [I2cDriver45] Enable HDC1080 temperature/humidity sensor (I2C address 0x40) (+1k5 code)
+// #define USE_IAQ // [I2cDriver46] Enable iAQ-core air quality sensor (I2C address 0x5a) (+0k6 code)
+// #define USE_AS3935 // [I2cDriver48] Enable AS3935 Franklin Lightning Sensor (I2C address 0x03) (+5k4 code)
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
@@ -513,6 +518,8 @@
#define MTX_ADDRESS6 0x76 // [DisplayAddress6] I2C address of sixth 8x8 matrix module
#define MTX_ADDRESS7 0x00 // [DisplayAddress7] I2C address of seventh 8x8 matrix module
#define MTX_ADDRESS8 0x00 // [DisplayAddress8] I2C address of eigth 8x8 matrix module
+ #define USE_DISPLAY_SEVENSEG // [DisplayModel 11] [I2cDriver47] Enable sevenseg display (I2C 0x70-0x77) (<+11k code)
+ #define SEVENSEG_ADDRESS1 0x70 // [DisplayAddress1] I2C address of first sevenseg matrix module
// #define USE_DISPLAY_SH1106 // [DisplayModel 7] [I2cDriver6] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
#endif // USE_I2C
@@ -661,7 +668,7 @@
/*********************************************************************************************\
* Optional firmware configurations
- * Select none or just one for optional features and sensors as configured in tasmota_post.h
+ * Select none or just one for optional features and sensors as configured in tasmota_configurations.h
* See RELEASENOTES.md for selected features
\*********************************************************************************************/
diff --git a/tasmota/settings.h b/tasmota/settings.h
index 5002382b0..ae4d2eaf9 100644
--- a/tasmota/settings.h
+++ b/tasmota/settings.h
@@ -211,6 +211,30 @@ typedef union {
};
} SensorCfg1;
+typedef union {
+ uint8_t data;
+ struct {
+ uint8_t nf_autotune : 1; // Autotune the NF Noise Level
+ uint8_t dist_autotune : 1; // Autotune Disturber on/off
+ uint8_t nf_autotune_both : 1; // Autotune over both Areas: INDOORS/OUDOORS
+ uint8_t mqtt_only_Light_Event : 1; // mqtt only if lightning Irq
+ uint8_t spare4 : 1;
+ uint8_t spare5 : 1;
+ uint8_t spare6 : 1;
+ uint8_t spare7 : 1;
+ };
+} As3935IntCfg;
+
+typedef union {
+ uint16_t data;
+ struct {
+ uint16_t nf_autotune_time : 4; // NF Noise Autotune Time
+ uint16_t dist_autotune_time : 4; // Disturber Autotune Time
+ uint16_t nf_autotune_min : 4; // Min Stages
+ uint16_t spare3 : 4;
+ };
+} As3935Param;
+
typedef struct {
uint32_t usage1_kWhtotal;
uint32_t usage2_kWhtotal;
@@ -221,7 +245,7 @@ typedef struct {
} EnergyUsage;
-typedef struct {
+typedef struct PACKED {
uint8_t fnid = 0;
uint8_t dpid = 0;
} TuyaFnidDpidMap;
@@ -229,7 +253,7 @@ typedef struct {
const uint32_t settings_text_size = 699; // Settings.text_pool[size] = Settings.display_model (2D2) - Settings.text_pool (017)
const uint8_t MAX_TUYA_FUNCTIONS = 16;
-struct SYSCFG {
+struct PACKED SYSCFG {
uint16_t cfg_holder; // 000 v6 header
uint16_t cfg_size; // 002
unsigned long save_flag; // 004
@@ -240,7 +264,7 @@ struct SYSCFG {
int16_t save_data; // 014
int8_t timezone; // 016
- // Start of char array storing all parameter strings
+ // Start of char array storing all parameter strings ********
char text_pool[101]; // 017 - was ota_url[101] - size is settings_text_size
@@ -276,7 +300,7 @@ struct SYSCFG {
char ex_button_topic[33]; // 290
char ex_mqtt_grptopic[33]; // 2B1
- // End of single char array of 698 chars max
+ // End of single char array of 698 chars max ****************
uint8_t display_model; // 2D2
uint8_t display_mode; // 2D3
@@ -470,10 +494,19 @@ struct SYSCFG {
uint8_t bri_preset_low; // F06
uint8_t bri_preset_high; // F07
int8_t hum_comp; // F08
- uint8_t channel; // F09
- uint8_t bssid[6]; // F0A
+ uint8_t wifi_channel; // F09
+ uint8_t wifi_bssid[6]; // F0A
+ uint8_t as3935_sensor_cfg[5]; // F10
+ As3935IntCfg as3935_functions; // F15
+ As3935Param as3935_parameter; // F16
+ uint64_t zb_ext_panid; // F18
+ uint64_t zb_precfgkey_l; // F20
+ uint64_t zb_precfgkey_h; // F28
+ uint16_t zb_pan_id; // F30
+ uint8_t zb_channel; // F32
+ uint8_t zb_free_byte; // F33
- uint8_t free_f10[168]; // F10
+ uint8_t free_f18[132]; // F34
uint16_t pulse_counter_debounce_low; // FB8
uint16_t pulse_counter_debounce_high; // FBA
diff --git a/tasmota/settings.ino b/tasmota/settings.ino
index caa87eb05..a1fc36fea 100644
--- a/tasmota/settings.ino
+++ b/tasmota/settings.ino
@@ -17,166 +17,6 @@
along with this program. If not, see .
*/
-#ifndef DOMOTICZ_UPDATE_TIMER
-#define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds) (Optional)
-#endif
-
-#ifndef EMULATION
-#define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo (single relay/light) or Hue Bridge emulation (multi relay/light) (EMUL_NONE, EMUL_WEMO or EMUL_HUE)
-#endif
-
-#ifndef MTX_ADDRESS1 // Add Display Support for up to eigth Matrices
-#define MTX_ADDRESS1 0
-#endif
-#ifndef MTX_ADDRESS2
-#define MTX_ADDRESS2 0
-#endif
-#ifndef MTX_ADDRESS3
-#define MTX_ADDRESS3 0
-#endif
-#ifndef MTX_ADDRESS4
-#define MTX_ADDRESS4 0
-#endif
-#ifndef MTX_ADDRESS5
-#define MTX_ADDRESS5 0
-#endif
-#ifndef MTX_ADDRESS6
-#define MTX_ADDRESS6 0
-#endif
-#ifndef MTX_ADDRESS7
-#define MTX_ADDRESS7 0
-#endif
-#ifndef MTX_ADDRESS8
-#define MTX_ADDRESS8 0
-#endif
-
-#ifndef HOME_ASSISTANT_DISCOVERY_ENABLE
-#define HOME_ASSISTANT_DISCOVERY_ENABLE 0
-#endif
-
-#ifndef LATITUDE
-#define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset
-#endif
-#ifndef LONGITUDE
-#define LONGITUDE 2.294442 // [Longitude] Your location to be used with sunrise and sunset
-#endif
-
-#ifndef WORKING_PERIOD
-#define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes
-#endif
-
-#ifndef COLOR_TEXT
-#define COLOR_TEXT "#000" // Global text color - Black
-#endif
-#ifndef COLOR_BACKGROUND
-#define COLOR_BACKGROUND "#fff" // Global background color - White
-#endif
-#ifndef COLOR_FORM
-#define COLOR_FORM "#f2f2f2" // Form background color - Greyish
-#endif
-#ifndef COLOR_INPUT_TEXT
-#define COLOR_INPUT_TEXT "#000" // Input text color - Black
-#endif
-#ifndef COLOR_INPUT
-#define COLOR_INPUT "#fff" // Input background color - White
-#endif
-#ifndef COLOR_CONSOLE_TEXT
-#define COLOR_CONSOLE_TEXT "#000" // Console text color - Black
-#endif
-#ifndef COLOR_CONSOLE
-#define COLOR_CONSOLE "#fff" // Console background color - White
-#endif
-#ifndef COLOR_TEXT_WARNING
-#define COLOR_TEXT_WARNING "#f00" // Warning text color - Red
-#endif
-#ifndef COLOR_TEXT_SUCCESS
-#define COLOR_TEXT_SUCCESS "#008000" // Success text color - Green
-#endif
-#ifndef COLOR_BUTTON_TEXT
-#define COLOR_BUTTON_TEXT "#fff" // Button text color - White
-#endif
-#ifndef COLOR_BUTTON
-#define COLOR_BUTTON "#1fa3ec" // Button color - Blueish
-#endif
-#ifndef COLOR_BUTTON_HOVER
-#define COLOR_BUTTON_HOVER "#0e70a4" // Button color when hovered over - Darker blueish
-#endif
-#ifndef COLOR_BUTTON_RESET
-#define COLOR_BUTTON_RESET "#d43535" // Restart/Reset/Delete button color - Redish
-#endif
-#ifndef COLOR_BUTTON_RESET_HOVER
-#define COLOR_BUTTON_RESET_HOVER "#931f1f" // Restart/Reset/Delete button color when hovered over - Darker redish
-#endif
-#ifndef COLOR_BUTTON_SAVE
-#define COLOR_BUTTON_SAVE "#47c266" // Save button color - Greenish
-#endif
-#ifndef COLOR_BUTTON_SAVE_HOVER
-#define COLOR_BUTTON_SAVE_HOVER "#5aaf6f" // Save button color when hovered over - Darker greenish
-#endif
-#ifndef COLOR_TIMER_TAB_TEXT
-#define COLOR_TIMER_TAB_TEXT "#fff" // Config timer tab text color - White
-#endif
-#ifndef COLOR_TIMER_TAB_BACKGROUND
-#define COLOR_TIMER_TAB_BACKGROUND "#999" // Config timer tab background color - Light grey
-#endif
-#ifndef COLOR_TITLE_TEXT
-#define COLOR_TITLE_TEXT COLOR_TEXT // Title text color defaults to global text color either dark or light
-#endif
-#ifndef IR_RCV_MIN_UNKNOWN_SIZE
-#define IR_RCV_MIN_UNKNOWN_SIZE 6 // Set the smallest sized "UNKNOWN" message packets we actually care about (default 6, max 255)
-#endif
-#ifndef ENERGY_OVERTEMP
-#define ENERGY_OVERTEMP 90 // Overtemp in Celsius
-#endif
-#ifndef DEFAULT_DIMMER_MAX
-#define DEFAULT_DIMMER_MAX 100
-#endif
-#ifndef DEFAULT_DIMMER_MIN
-#define DEFAULT_DIMMER_MIN 0
-#endif
-#ifndef DEFAULT_LIGHT_DIMMER
-#define DEFAULT_LIGHT_DIMMER 10
-#endif
-#ifndef DEFAULT_LIGHT_COMPONENT
-#define DEFAULT_LIGHT_COMPONENT 255
-#endif
-#ifndef CORS_ENABLED_ALL
-#define CORS_ENABLED_ALL "*"
-#endif
-
-
-enum WebColors {
- COL_TEXT, COL_BACKGROUND, COL_FORM,
- COL_INPUT_TEXT, COL_INPUT, COL_CONSOLE_TEXT, COL_CONSOLE,
- COL_TEXT_WARNING, COL_TEXT_SUCCESS,
- COL_BUTTON_TEXT, COL_BUTTON, COL_BUTTON_HOVER, COL_BUTTON_RESET, COL_BUTTON_RESET_HOVER, COL_BUTTON_SAVE, COL_BUTTON_SAVE_HOVER,
- COL_TIMER_TAB_TEXT, COL_TIMER_TAB_BACKGROUND, COL_TITLE,
- COL_LAST };
-
-const char kWebColors[] PROGMEM =
- COLOR_TEXT "|" COLOR_BACKGROUND "|" COLOR_FORM "|"
- COLOR_INPUT_TEXT "|" COLOR_INPUT "|" COLOR_CONSOLE_TEXT "|" COLOR_CONSOLE "|"
- COLOR_TEXT_WARNING "|" COLOR_TEXT_SUCCESS "|"
- COLOR_BUTTON_TEXT "|" COLOR_BUTTON "|" COLOR_BUTTON_HOVER "|" COLOR_BUTTON_RESET "|" COLOR_BUTTON_RESET_HOVER "|" COLOR_BUTTON_SAVE "|" COLOR_BUTTON_SAVE_HOVER "|"
- COLOR_TIMER_TAB_TEXT "|" COLOR_TIMER_TAB_BACKGROUND "|" COLOR_TITLE_TEXT;
-
-enum TasmotaSerialConfig {
- TS_SERIAL_5N1, TS_SERIAL_6N1, TS_SERIAL_7N1, TS_SERIAL_8N1,
- TS_SERIAL_5N2, TS_SERIAL_6N2, TS_SERIAL_7N2, TS_SERIAL_8N2,
- TS_SERIAL_5E1, TS_SERIAL_6E1, TS_SERIAL_7E1, TS_SERIAL_8E1,
- TS_SERIAL_5E2, TS_SERIAL_6E2, TS_SERIAL_7E2, TS_SERIAL_8E2,
- TS_SERIAL_5O1, TS_SERIAL_6O1, TS_SERIAL_7O1, TS_SERIAL_8O1,
- TS_SERIAL_5O2, TS_SERIAL_6O2, TS_SERIAL_7O2, TS_SERIAL_8O2 };
-
-const uint8_t kTasmotaSerialConfig[] PROGMEM = {
- SERIAL_5N1, SERIAL_6N1, SERIAL_7N1, SERIAL_8N1,
- SERIAL_5N2, SERIAL_6N2, SERIAL_7N2, SERIAL_8N2,
- SERIAL_5E1, SERIAL_6E1, SERIAL_7E1, SERIAL_8E1,
- SERIAL_5E2, SERIAL_6E2, SERIAL_7E2, SERIAL_8E2,
- SERIAL_5O1, SERIAL_6O1, SERIAL_7O1, SERIAL_8O1,
- SERIAL_5O2, SERIAL_6O2, SERIAL_7O2, SERIAL_8O2
-};
-
/*********************************************************************************************\
* RTC memory
\*********************************************************************************************/
@@ -200,14 +40,14 @@ void RtcSettingsSave(void)
{
if (GetRtcSettingsCrc() != rtc_settings_crc) {
RtcSettings.valid = RTC_MEM_VALID;
- ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
+ ESP_rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
rtc_settings_crc = GetRtcSettingsCrc();
}
}
void RtcSettingsLoad(void)
{
- ESP.rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); // 0x290
+ ESP_rtcUserMemoryRead(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); // 0x290
if (RtcSettings.valid != RTC_MEM_VALID) {
memset(&RtcSettings, 0, sizeof(RTCMEM));
RtcSettings.valid = RTC_MEM_VALID;
@@ -247,7 +87,7 @@ void RtcRebootSave(void)
{
if (GetRtcRebootCrc() != rtc_reboot_crc) {
RtcReboot.valid = RTC_MEM_VALID;
- ESP.rtcUserMemoryWrite(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT));
+ ESP_rtcUserMemoryWrite(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT));
rtc_reboot_crc = GetRtcRebootCrc();
}
}
@@ -260,7 +100,7 @@ void RtcRebootReset(void)
void RtcRebootLoad(void)
{
- ESP.rtcUserMemoryRead(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT)); // 0x280
+ ESP_rtcUserMemoryRead(100 - sizeof(RTCRBT), (uint32_t*)&RtcReboot, sizeof(RTCRBT)); // 0x280
if (RtcReboot.valid != RTC_MEM_VALID) {
memset(&RtcReboot, 0, sizeof(RTCRBT));
RtcReboot.valid = RTC_MEM_VALID;
@@ -301,6 +141,8 @@ extern "C" {
}
#include "eboot_command.h"
+#ifdef ESP8266
+
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) || defined(ARDUINO_ESP8266_RELEASE_2_5_0) || defined(ARDUINO_ESP8266_RELEASE_2_5_1) || defined(ARDUINO_ESP8266_RELEASE_2_5_2)
extern "C" uint32_t _SPIFFS_end;
@@ -328,6 +170,9 @@ const uint32_t SPIFFS_END = ((uint32_t)&_FS_end - 0x40200000) / SPI_FLASH_SEC_SI
// Version 4.2 config = eeprom area
const uint32_t SETTINGS_LOCATION = SPIFFS_END; // No need for SPIFFS as it uses EEPROM area
+
+#endif // ESP8266
+
// Version 5.2 allow for more flash space
const uint8_t CFG_ROTATES = 8; // Number of flash sectors used (handles uploads)
@@ -341,6 +186,7 @@ uint8_t *settings_buffer = nullptr;
*/
void SetFlashModeDout(void)
{
+#ifdef ESP8266
uint8_t *_buffer;
uint32_t address;
@@ -358,10 +204,13 @@ void SetFlashModeDout(void)
}
}
delete[] _buffer;
+#endif // ESP8266
}
bool VersionCompatible(void)
{
+#ifdef ESP8266
+
if (Settings.flag3.compatibility_check) {
return true;
}
@@ -404,6 +253,8 @@ bool VersionCompatible(void)
return false;
}
+#endif // ESP8266
+
return true;
}
@@ -479,7 +330,7 @@ void SettingsSaveAll(void)
void UpdateQuickPowerCycle(bool update)
{
- if (Settings.flag3.fast_power_cycle_disable) { return; }
+ if (Settings.flag3.fast_power_cycle_disable) { return; } // SetOption65 - Disable fast power cycle detection for device reset
uint32_t pc_register;
uint32_t pc_location = SETTINGS_LOCATION - CFG_ROTATES;
@@ -638,6 +489,7 @@ void SettingsSave(uint8_t rotate)
Settings.cfg_crc = GetSettingsCrc(); // Keep for backward compatibility in case of fall-back just after upgrade
Settings.cfg_crc32 = GetSettingsCrc32();
+#ifdef ESP8266
if (ESP.flashEraseSector(settings_location)) {
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
}
@@ -648,6 +500,9 @@ void SettingsSave(uint8_t rotate)
delay(1);
}
}
+#else // ESP32
+ SettingsSaveMain(&Settings, sizeof(SYSCFG));
+#endif // ESP8266
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(SYSCFG));
@@ -672,8 +527,7 @@ void SettingsLoad(void)
uint16_t cfg_holder = 0;
for (uint32_t i = 0; i < CFG_ROTATES; i++) {
flash_location--;
- ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
-
+ ESP_flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
bool valid = false;
if (Settings.version > 0x06000000) {
bool almost_valid = (Settings.cfg_crc32 == GetSettingsCrc32());
@@ -684,7 +538,7 @@ void SettingsLoad(void)
if (almost_valid && (0 == cfg_holder)) { cfg_holder = Settings.cfg_holder; } // At FB always active cfg_holder
valid = (cfg_holder == Settings.cfg_holder);
} else {
- ESP.flashRead((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
+ ESP_flashReadHeader((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH));
valid = (Settings.cfg_holder == _SettingsH.cfg_holder);
}
if (valid) {
@@ -700,7 +554,7 @@ void SettingsLoad(void)
delay(1);
}
if (settings_location > 0) {
- ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
+ ESP_flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG));
AddLog_P2(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
}
@@ -737,6 +591,7 @@ void EspErase(uint32_t start_sector, uint32_t end_sector)
}
}
+#ifdef ESP8266
void SettingsErase(uint8_t type)
{
/*
@@ -791,6 +646,7 @@ void SettingsErase(uint8_t type)
EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely
#endif // FIRMWARE_MINIMAL
}
+#endif // ESP8266
void SettingsSdkErase(void)
{
@@ -1188,6 +1044,8 @@ void SettingsEnableAllI2cDrivers(void)
void SettingsDelta(void)
{
if (Settings.version != VERSION) { // Fix version dependent changes
+
+#ifdef ESP8266
if (Settings.version < 0x06000000) {
Settings.cfg_size = sizeof(SYSCFG);
Settings.cfg_crc = GetSettingsCrc();
@@ -1475,6 +1333,7 @@ void SettingsDelta(void)
if (Settings.version < 0x08020003) {
SettingsUpdateText(SET_TEMPLATE_NAME, Settings.user_template_name);
}
+#endif // ESP8266
Settings.version = VERSION;
SettingsSave(1);
diff --git a/tasmota/support.ino b/tasmota/support.ino
index 81cb1b002..2a794d545 100644
--- a/tasmota/support.ino
+++ b/tasmota/support.ino
@@ -109,7 +109,7 @@ String GetResetReason(void)
strncpy_P(buff, PSTR(D_JSON_BLOCKED_LOOP), sizeof(buff));
return String(buff);
} else {
- return ESP.getResetReason();
+ return ESP_getResetReason();
}
}
@@ -213,7 +213,7 @@ char* ulltoa(unsigned long long value, char *str, int radix)
}
// see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c
-// char* ToHex_P(unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0'); in tasmota_post.h
+// char* ToHex_P(unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0'); in tasmota_globals.h
char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween)
{
// ToHex_P(in, insz, out, outz) -> "12345667"
@@ -1660,7 +1660,7 @@ void Syslog(void)
memmove(log_data + strlen(syslog_preamble), log_data, sizeof(log_data) - strlen(syslog_preamble));
log_data[sizeof(log_data) -1] = '\0';
memcpy(log_data, syslog_preamble, strlen(syslog_preamble));
- PortUdp.write(log_data, strlen(log_data));
+ PortUdp_write(log_data, strlen(log_data));
PortUdp.endPacket();
delay(1); // Add time for UDP handling (#5512)
} else {
diff --git a/tasmota/support_button.ino b/tasmota/support_button.ino
index f30f3a287..4b41c2a74 100644
--- a/tasmota/support_button.ino
+++ b/tasmota/support_button.ino
@@ -119,6 +119,7 @@ void ButtonHandler(void)
uint8_t button = NOT_PRESSED;
uint8_t button_present = 0;
+#ifdef ESP8266
if (!button_index && ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type))) {
button_present = 1;
if (Button.dual_code) {
@@ -131,7 +132,9 @@ void ButtonHandler(void)
Button.dual_code = 0;
}
}
- else if (pin[GPIO_KEY1 +button_index] < 99) {
+ else
+#endif // ESP8266
+ if (pin[GPIO_KEY1 +button_index] < 99) {
button_present = 1;
button = (digitalRead(pin[GPIO_KEY1 +button_index]) != bitRead(Button.inverted_mask, button_index));
}
@@ -153,6 +156,7 @@ void ButtonHandler(void)
if (XdrvCall(FUNC_BUTTON_PRESSED)) {
// Serviced
}
+#ifdef ESP8266
else if (SONOFF_4CHPRO == my_module_type) {
if (Button.hold_timer[button_index]) { Button.hold_timer[button_index]--; }
@@ -172,6 +176,7 @@ void ButtonHandler(void)
}
}
}
+#endif // ESP8266
else {
if ((PRESSED == button) && (NOT_PRESSED == Button.last_state[button_index])) {
if (Settings.flag.button_single) { // SetOption13 (0) - Allow only single button press for immediate action
@@ -227,9 +232,12 @@ void ButtonHandler(void)
if (!restart_flag && !Button.hold_timer[button_index] && (Button.press_counter[button_index] > 0) && (Button.press_counter[button_index] < MAX_BUTTON_COMMANDS +3)) {
bool single_press = false;
if (Button.press_counter[button_index] < 3) { // Single or Double press
+#ifdef ESP8266
if ((SONOFF_DUAL_R2 == my_module_type) || (SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) {
single_press = true;
- } else {
+ } else
+#endif // ESP8266
+ {
single_press = (Settings.flag.button_swap +1 == Button.press_counter[button_index]); // SetOption11 (0)
if ((1 == Button.present) && (2 == devices_present)) { // Single Button with two devices only
if (Settings.flag.button_swap) { // SetOption11 (0)
diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino
index 37fa195fc..133298010 100644
--- a/tasmota/support_command.ino
+++ b/tasmota/support_command.ino
@@ -182,7 +182,16 @@ void CommandHandler(char* topicBuf, char* dataBuf, uint32_t data_len)
data_len--;
}
- bool grpflg = (strstr(topicBuf, SettingsText(SET_MQTT_GRP_TOPIC)) != nullptr);
+ bool grpflg = false;
+ uint32_t real_index = SET_MQTT_GRP_TOPIC;
+ for (uint32_t i = 0; i < MAX_GROUP_TOPICS; i++) {
+ if (1 == i) { real_index = SET_MQTT_GRP_TOPIC2 -1; }
+ char *group_topic = SettingsText(real_index +i);
+ if (*group_topic && strstr(topicBuf, group_topic) != nullptr) {
+ grpflg = true;
+ break;
+ }
+ }
char stemp1[TOPSZ];
GetFallbackTopic_P(stemp1, ""); // Full Fallback topic = cmnd/DVES_xxxxxxxx_fb/
@@ -417,7 +426,7 @@ void CmndStatus(void)
"\"Hardware\":\"%s\""
"%s}}"),
my_version, my_image, GetBuildDateAndTime().c_str(),
- ESP.getBootVersion(), ESP.getSdkVersion(),
+ ESP_getBootVersion(), ESP.getSdkVersion(),
GetDeviceHardware().c_str(),
GetStatistics().c_str());
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "2"));
@@ -439,7 +448,7 @@ void CmndStatus(void)
D_JSON_PROGRAMFLASHSIZE "\":%d,\"" D_JSON_FLASHSIZE "\":%d,\"" D_JSON_FLASHCHIPID "\":\"%06X\",\"" D_JSON_FLASHMODE "\":%d,\""
D_JSON_FEATURES "\":[\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\",\"%08X\"]"),
ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024,
- ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipId(), ESP.getFlashChipMode(),
+ ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP_getFlashChipId(), ESP.getFlashChipMode(),
LANGUAGE_LCID, feature_drv1, feature_drv2, feature_sns1, feature_sns2, feature5, feature6);
XsnsDriverState();
ResponseAppend_P(PSTR(",\"Sensors\":"));
@@ -571,10 +580,10 @@ void CmndSleep(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 251)) {
Settings.sleep = XdrvMailbox.payload;
- sleep = XdrvMailbox.payload;
+ ssleep = XdrvMailbox.payload;
WiFiSetSleepMode();
}
- Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.sleep, sleep);
+ Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings.sleep, ssleep);
}
@@ -637,7 +646,10 @@ void CmndRestart(void)
void CmndPowerOnState(void)
{
- if (my_module_type != MOTOR) {
+#ifdef ESP8266
+ if (my_module_type != MOTOR)
+#endif // ESP8266
+ {
/* 0 = Keep relays off after power on
* 1 = Turn relays on after power on, if PulseTime set wait for PulseTime seconds, and turn relays off
* 2 = Toggle relays after power on
diff --git a/tasmota/support_crash_recorder.ino b/tasmota/support_crash_recorder.ino
index cc9721cb4..dd0834550 100644
--- a/tasmota/support_crash_recorder.ino
+++ b/tasmota/support_crash_recorder.ino
@@ -17,6 +17,8 @@
along with this program. If not, see .
*/
+#ifdef ESP8266
+
const uint32_t crash_magic = 0x53415400; // Stack trace magic number (TASx)
const uint32_t crash_rtc_offset = 32; // Offset in RTC memory skipping OTA used block
const uint32_t crash_dump_max_len = 31; // Dump only 31 call addresses to satisfy max JSON length of about 600 characters
@@ -109,3 +111,5 @@ void CrashDump(void)
ResponseJsonEnd();
}
+
+#endif // ESP8266
\ No newline at end of file
diff --git a/tasmota/support_device_groups.ino b/tasmota/support_device_groups.ino
index d350575c1..e1719f59e 100644
--- a/tasmota/support_device_groups.ino
+++ b/tasmota/support_device_groups.ino
@@ -20,6 +20,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+
#ifdef USE_DEVICE_GROUPS
//#define DEVICE_GROUPS_DEBUG
@@ -163,7 +164,7 @@ void SendDeviceGroupPacket(IPAddress ip, char * packet, int len, const char * la
if (!ip) ip = IPAddress(239,255,255,250);
for (int attempt = 1; attempt <= 5; attempt++) {
if (PortUdp.beginPacket(ip, 1900)) {
- PortUdp.write(packet, len);
+ PortUdp_write(packet, len);
if (PortUdp.endPacket()) return;
}
delay(10);
@@ -552,7 +553,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
#ifdef DEVICE_GROUPS_DEBUG
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via multicast, sequence=%u"), device_group->message_length, device_group->group_name, device_group->message[device_group->message_header_length] | device_group->message[device_group->message_header_length + 1] << 8);
#endif // DEVICE_GROUPS_DEBUG
- SendDeviceGroupPacket(0, device_group->message, device_group->message_length, PSTR("Multicast"));
+ SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, device_group->message_length, PSTR("Multicast"));
uint32_t now = millis();
if (message_type == DGR_MSGTYP_UPDATE_MORE_TO_COME) {
@@ -857,7 +858,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex
#ifdef DEVICE_GROUPS_DEBUG
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending initial status request for group %s"), device_group->group_name);
#endif // DEVICE_GROUPS_DEBUG
- SendDeviceGroupPacket(0, device_group->message, device_group->message_length, PSTR("Initial"));
+ SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, device_group->message_length, PSTR("Initial"));
device_group->message[device_group->message_header_length + 2] = DGR_FLAG_STATUS_REQUEST; // The reset flag is on only for the first packet - turn it off now
device_group->next_ack_check_time = now + 200;
}
@@ -941,7 +942,7 @@ AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: Ckecking next_check_time=%u, now=%u"), nex
#ifdef DEVICE_GROUPS_DEBUG
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending device group %s announcement"), device_group->group_name);
#endif // DEVICE_GROUPS_DEBUG
- SendDeviceGroupPacket(0, device_group->message, BeginDeviceGroupMessage(device_group, DGR_FLAG_ANNOUNCEMENT, true) - device_group->message, PSTR("Announcement"));
+ SendDeviceGroupPacket(IPAddress(0,0,0,0), device_group->message, BeginDeviceGroupMessage(device_group, DGR_FLAG_ANNOUNCEMENT, true) - device_group->message, PSTR("Announcement"));
device_group->next_announcement_time = now + DGR_ANNOUNCEMENT_INTERVAL + random(10000);
}
if (device_group->next_announcement_time < next_check_time) next_check_time = device_group->next_announcement_time;
diff --git a/tasmota/support_esp32.ino b/tasmota/support_esp32.ino
new file mode 100644
index 000000000..1e2a4e0ca
--- /dev/null
+++ b/tasmota/support_esp32.ino
@@ -0,0 +1,177 @@
+/*
+ support_esp32.ino - ESP32 specific code for Tasmota
+
+ Copyright (C) 2020 Theo Arends / Jörg Schüler-Maroldt
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef ESP32
+
+#include
+#include
+
+void SettingsErase(uint8_t type)
+{
+ if (1 == type) // SDK parameter area
+ {
+ }
+ else if (2 == type) // Tasmota parameter area (0x0F3xxx - 0x0FBFFF)
+ {
+ }
+ else if (3 == type) // Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
+ {
+ }
+
+ noInterrupts();
+ nvs_handle handle;
+ nvs_open("main", NVS_READWRITE, &handle);
+ nvs_erase_all(handle);
+ nvs_commit(handle);
+ nvs_close(handle);
+ interrupts();
+
+ AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " t=%d"), type);
+}
+
+void SettingsLoad(const char *sNvsName, const char *sName, void *pSettings, unsigned nSettingsLen)
+{
+ noInterrupts();
+ nvs_handle handle;
+ size_t size;
+ nvs_open(sNvsName, NVS_READONLY, &handle);
+ size = nSettingsLen;
+ nvs_get_blob(handle, sName, pSettings, &size);
+ nvs_close(handle);
+ interrupts();
+}
+
+void SettingsSave(const char *sNvsName, const char *sName, const void *pSettings, unsigned nSettingsLen)
+{
+ nvs_handle handle;
+ noInterrupts();
+ nvs_open(sNvsName, NVS_READWRITE, &handle);
+ nvs_set_blob(handle, sName, pSettings, nSettingsLen);
+ nvs_commit(handle);
+ nvs_close(handle);
+ interrupts();
+}
+
+void ESP32_flashRead(uint32_t offset, uint32_t *data, size_t size)
+{
+ SettingsLoad("main", "Settings", data, size);
+}
+
+void ESP32_flashReadHeader(uint32_t offset, uint32_t *data, size_t size)
+{
+ SettingsLoad("main", "SettingsH", data, size);
+}
+
+void SettingsSaveMain(const void *pSettings, unsigned nSettingsLen)
+{
+ SettingsSave("main", "Settings", pSettings, nSettingsLen);
+}
+
+/*
+void SettingsLoadMain(void *pSettings, unsigned nSettingsLen)
+{
+ SettingsLoad("main", "Settings", pSettings, nSettingsLen);
+}
+
+void SettingsLoadMainH(void *pSettingsH, unsigned nSettingsLenH)
+{
+ SettingsLoad("main", "SettingsH", pSettingsH, nSettingsLenH);
+}
+*/
+
+void SettingsLoadUpg(void *pSettings, unsigned nSettingsLen)
+{
+ SettingsLoad("upg", "Settings", pSettings, nSettingsLen);
+}
+
+void SettingsLoadUpgH(void *pSettings, unsigned nSettingsLen)
+{
+ SettingsLoad("upg", "SettingsH", pSettings, nSettingsLen);
+}
+
+//
+// sntp emulation
+//
+static bool bNetIsTimeSync = false;
+//
+void SntpInit()
+{
+ bNetIsTimeSync = true;
+}
+
+uint32_t SntpGetCurrentTimestamp(void)
+{
+ time_t now = 0;
+ if (bNetIsTimeSync || ntp_force_sync)
+ {
+ //Serial_DebugX(("timesync configTime %d\n", ntp_force_sync, bNetIsTimeSync));
+ // init to UTC Time
+ configTime(0, 0, SettingsText(SET_NTPSERVER1), SettingsText(SET_NTPSERVER2), SettingsText(SET_NTPSERVER3));
+ bNetIsTimeSync = false;
+ ntp_force_sync = false;
+ }
+ time(&now);
+ return now;
+}
+
+//
+// Crash stuff
+//
+
+void CrashDump(void)
+{
+}
+
+bool CrashFlag(void)
+{
+ return false;
+}
+
+void CrashDumpClear(void)
+{
+}
+void CmndCrash(void)
+{
+ /*
+ volatile uint32_t dummy;
+ dummy = *((uint32_t*) 0x00000000);
+*/
+}
+
+// Do an infinite loop to trigger WDT watchdog
+void CmndWDT(void)
+{
+ /*
+ volatile uint32_t dummy = 0;
+ while (1) {
+ dummy++;
+ }
+*/
+}
+// This will trigger the os watch after OSWATCH_RESET_TIME (=120) seconds
+void CmndBlockedLoop(void)
+{
+ /*
+ while (1) {
+ delay(1000);
+ }
+*/
+}
+
+#endif // ESP32
diff --git a/tasmota/support_esptool.ino b/tasmota/support_esptool.ino
index 5bb82f999..efde513fc 100644
--- a/tasmota/support_esptool.ino
+++ b/tasmota/support_esptool.ino
@@ -17,7 +17,10 @@
along with this program. If not, see .
*/
+#ifdef ESP8266
#define USE_ESPTOOL
+#endif // ESP8266
+
#ifdef USE_ESPTOOL
/*********************************************************************************************\
* EspTool Erase function based on Version 2.8
diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino
index 201711e48..f9dac8b4a 100644
--- a/tasmota/support_features.ino
+++ b/tasmota/support_features.ino
@@ -542,11 +542,18 @@ void GetFeatures(void)
#ifdef USE_HDC1080
feature6 |= 0x00000008; // xsns_65_hdc1080.ino
#endif
-
-// feature6 |= 0x00000010;
-// feature6 |= 0x00000020;
-// feature6 |= 0x00000040;
-// feature6 |= 0x00000080;
+#ifdef USE_IAQ
+ feature6 |= 0x00000010; // xsns_66_iAQ.ino
+#endif
+#ifdef USE_DISPLAY_SEVENSEG
+ feature6 |= 0x00000020; // xdsp_11_sevenseg.ino
+#endif
+#ifdef USE_AS3935
+ feature6 |= 0x00000040; // xsns_67_as3935.ino
+#endif
+#ifdef USE_PING
+ feature6 |= 0x00000080; // xdrv_38_ping.ino
+#endif
// feature6 |= 0x00000100;
// feature6 |= 0x00000200;
diff --git a/tasmota/support_legacy_cores.ino b/tasmota/support_legacy_cores.ino
index 0d429c75f..46546ff1d 100644
--- a/tasmota/support_legacy_cores.ino
+++ b/tasmota/support_legacy_cores.ino
@@ -162,7 +162,7 @@ void* memmove_P(void *dest, const void *src, size_t n)
* Core overrides
\*********************************************************************************************/
-// Add below line to tasmota_post.h
+// Add below line to tasmota_globals.h
// extern "C" void resetPins();
void resetPins()
{
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index a0a3bacaf..44954ca26 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -210,6 +210,7 @@ void SetDevicePower(power_t rpower, uint32_t source)
if (XdrvCall(FUNC_SET_DEVICE_POWER)) { // Set power state and stop if serviced
// Serviced
}
+#ifdef ESP8266
else if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) {
Serial.write(0xA0);
Serial.write(0x04);
@@ -221,7 +222,9 @@ void SetDevicePower(power_t rpower, uint32_t source)
else if (EXS_RELAY == my_module_type) {
SetLatchingRelay(rpower, 1);
}
- else {
+ else
+#endif // ESP8266
+ {
for (uint32_t i = 0; i < devices_present; i++) {
power_t state = rpower &1;
if (i < MAX_RELAYS) {
@@ -279,9 +282,11 @@ void SetAllPower(uint32_t state, uint32_t source)
void SetPowerOnState(void)
{
+#ifdef ESP8266
if (MOTOR == my_module_type) {
Settings.poweronstate = POWER_ALL_ON; // Needs always on else in limbo!
}
+#endif // ESP8266
if (POWER_ALL_ALWAYS_ON == Settings.poweronstate) {
SetDevicePower(1, SRC_RESTART);
} else {
@@ -625,7 +630,7 @@ void MqttShowState(void)
ResponseAppend_P(PSTR(",\"" D_JSON_HEAPSIZE "\":%d,\"SleepMode\":\"%s\",\"Sleep\":%u,\"LoadAvg\":%u,\"MqttCount\":%u"),
ESP.getFreeHeap()/1024, GetTextIndexed(stemp1, sizeof(stemp1), Settings.flag3.sleep_normal, kSleepMode), // SetOption60 - Enable normal sleep instead of dynamic sleep
- sleep, loop_load_avg, MqttConnectCount());
+ ssleep, loop_load_avg, MqttConnectCount());
for (uint32_t i = 1; i <= devices_present; i++) {
#ifdef USE_LIGHT
@@ -815,8 +820,10 @@ void PerformEverySecond(void)
}
}
+#ifndef ARDUINO_ESP8266_RELEASE_2_3_0
// Wifi keep alive to send Gratuitous ARP
wifiKeepAlive();
+#endif // ARDUINO_ESP8266_RELEASE_2_3_0
}
/*-------------------------------------------------------------------------------------------*\
@@ -901,9 +908,11 @@ void Every250mSeconds(void)
}
if (Settings.ledstate &1 && (pin[GPIO_LEDLNK] < 99 || !(blinks || restart_flag || ota_state_flag)) ) {
bool tstate = power & Settings.ledmask;
+#ifdef ESP8266
if ((SONOFF_TOUCH == my_module_type) || (SONOFF_T11 == my_module_type) || (SONOFF_T12 == my_module_type) || (SONOFF_T13 == my_module_type)) {
tstate = (!power) ? 1 : 0; // As requested invert signal for Touch devices to find them in the dark
}
+#endif // ESP8266
SetLedPower(tstate);
}
@@ -1211,13 +1220,14 @@ void SerialInput(void)
delay(0);
serial_in_byte = Serial.read();
+#ifdef ESP8266
/*-------------------------------------------------------------------------------------------*\
* Sonoff dual and ch4 19200 baud serial interface
\*-------------------------------------------------------------------------------------------*/
if ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)) {
serial_in_byte = ButtonSerial(serial_in_byte);
}
-
+#endif // ESP8266
/*-------------------------------------------------------------------------------------------*/
if (XdrvCall(FUNC_SERIAL)) {
@@ -1318,7 +1328,15 @@ void GpioInit(void)
if (!ValidModule(Settings.module)) {
uint32_t module = MODULE;
- if (!ValidModule(MODULE)) { module = SONOFF_BASIC; }
+ if (!ValidModule(MODULE)) {
+#ifdef ESP8266
+ module = SONOFF_BASIC;
+#endif // ESP8266
+#ifdef ESP32
+ module = WEMOS;
+#endif // ESP32
+ }
+
Settings.module = module;
Settings.last_module = module;
}
@@ -1415,7 +1433,9 @@ void GpioInit(void)
if (mpin) pin[mpin] = i;
}
+#ifdef ESP8266
if ((2 == pin[GPIO_TXD]) || (H801 == my_module_type)) { Serial.set_tx(2); }
+#endif // ESP8266
analogWriteRange(Settings.pwm_range); // Default is 1023 (Arduino.h)
analogWriteFreq(Settings.pwm_frequency); // Default is 1000 (core_esp8266_wiring_pwm.c)
@@ -1460,6 +1480,7 @@ void GpioInit(void)
if (XdrvCall(FUNC_MODULE_INIT)) {
// Serviced
}
+#ifdef ESP8266
else if (YTF_IR_BRIDGE == my_module_type) {
ClaimSerial(); // Stop serial loopback mode
// devices_present = 1;
@@ -1477,6 +1498,7 @@ void GpioInit(void)
SetSerial(19200, TS_SERIAL_8N1);
}
#endif // USE_SONOFF_SC
+#endif // ESP8266
for (uint32_t i = 0; i < MAX_PWMS; i++) { // Basic PWM control only
if (pin[GPIO_PWM1 +i] < 99) {
@@ -1495,10 +1517,12 @@ void GpioInit(void)
if (pin[GPIO_REL1 +i] < 99) {
pinMode(pin[GPIO_REL1 +i], OUTPUT);
devices_present++;
+#ifdef ESP8266
if (EXS_RELAY == my_module_type) {
digitalWrite(pin[GPIO_REL1 +i], bitRead(rel_inverted, i) ? 1 : 0);
if (i &1) { devices_present--; }
}
+#endif // ESP8266
}
}
diff --git a/tasmota/support_wifi.ino b/tasmota/support_wifi.ino
index c7ac57106..dc4016b59 100644
--- a/tasmota/support_wifi.ino
+++ b/tasmota/support_wifi.ino
@@ -156,10 +156,10 @@ void WiFiSetSleepMode(void)
// Sleep explanation: https://github.com/esp8266/Arduino/blob/3f0c601cfe81439ce17e9bd5d28994a7ed144482/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L255
#if defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2)
#else // Enabled in 2.3.0, 2.4.0 and stage
- if (sleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
- WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
+ if (ssleep && Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
+ WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times
} else {
- WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default)
+ WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default)
}
#endif
WifiSetOutputPower();
@@ -403,9 +403,9 @@ void WifiCheckIp(void)
Settings.ip_address[3] = (uint32_t)WiFi.dnsIP();
// Save current AP parameters for quick reconnect
- Settings.channel = WiFi.channel();
+ Settings.wifi_channel = WiFi.channel();
uint8_t *bssid = WiFi.BSSID();
- memcpy((void*) &Settings.bssid, (void*) bssid, sizeof(Settings.bssid));
+ memcpy((void*) &Settings.wifi_bssid, (void*) bssid, sizeof(Settings.wifi_bssid));
}
Wifi.status = WL_CONNECTED;
#ifdef USE_DISCOVERY
@@ -428,7 +428,7 @@ void WifiCheckIp(void)
break;
case WL_NO_SSID_AVAIL:
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_AP_NOT_REACHED));
- Settings.channel = 0; // Disable stored AP
+ Settings.wifi_channel = 0; // Disable stored AP
if (WIFI_WAIT == Settings.sta_config) {
Wifi.retry = Wifi.retry_init;
} else {
@@ -442,7 +442,7 @@ void WifiCheckIp(void)
break;
case WL_CONNECT_FAILED:
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_WRONG_PASSWORD));
- Settings.channel = 0; // Disable stored AP
+ Settings.wifi_channel = 0; // Disable stored AP
if (Wifi.retry > (Wifi.retry_init / 2)) {
Wifi.retry = Wifi.retry_init / 2;
}
@@ -453,10 +453,10 @@ void WifiCheckIp(void)
default: // WL_IDLE_STATUS and WL_DISCONNECTED
if (!Wifi.retry || ((Wifi.retry_init / 2) == Wifi.retry)) {
AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_AP_TIMEOUT));
- Settings.channel = 0; // Disable stored AP
+ Settings.wifi_channel = 0; // Disable stored AP
} else {
if (!strlen(SettingsText(SET_STASSID1)) && !strlen(SettingsText(SET_STASSID2))) {
- Settings.channel = 0; // Disable stored AP
+ Settings.wifi_channel = 0; // Disable stored AP
wifi_config_tool = WIFI_MANAGER; // Skip empty SSIDs and start Wifi config tool
Wifi.retry = 0;
} else {
@@ -471,7 +471,7 @@ void WifiCheckIp(void)
}
} else {
if (Wifi.retry_init == Wifi.retry) {
- WifiBegin(3, Settings.channel); // Select default SSID
+ WifiBegin(3, Settings.wifi_channel); // Select default SSID
}
if ((Settings.sta_config != WIFI_WAIT) && ((Wifi.retry_init / 2) == Wifi.retry)) {
WifiBegin(2, 0); // Select alternate SSID
@@ -659,7 +659,7 @@ void WifiConnect(void)
Wifi.retry = Wifi.retry_init;
Wifi.counter = 1;
- memcpy((void*) &Wifi.bssid, (void*) Settings.bssid, sizeof(Wifi.bssid));
+ memcpy((void*) &Wifi.bssid, (void*) Settings.wifi_bssid, sizeof(Wifi.bssid));
#ifdef WIFI_RF_PRE_INIT
if (rf_pre_init_flag) {
@@ -709,9 +709,10 @@ void EspRestart(void)
WifiShutdown(true);
CrashDumpClear(); // Clear the stack dump in RTC
// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0
- ESP.reset();
+ ESP_reset();
}
+#ifndef ARDUINO_ESP8266_RELEASE_2_3_0
//
// Gratuitous ARP, backported from https://github.com/esp8266/Arduino/pull/6889
//
@@ -759,3 +760,4 @@ void wifiKeepAlive(void) {
SetNextTimeInterval(wifiTimer, wifiTimerSec * 1000);
}
}
+#endif // ARDUINO_ESP8266_RELEASE_2_3_0
\ No newline at end of file
diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h
index 4b2e218b3..e6861ee97 100644
--- a/tasmota/tasmota.h
+++ b/tasmota/tasmota.h
@@ -30,7 +30,6 @@
* Default sensor states
\*********************************************************************************************/
-#define CODE_IMAGE 0
#define CODE_IMAGE_STR "tasmota"
#define USE_LIGHT // Enable light control
@@ -42,8 +41,14 @@
* Power Type
\*********************************************************************************************/
+#ifdef ESP8266
typedef unsigned long power_t; // Power (Relay) type
const uint32_t POWER_MASK = 0xffffffffUL; // Power (Relay) full mask
+#endif // ESP8266
+#ifdef ESP32
+typedef uint64_t power_t; // Power (Relay) type
+const uint64_t POWER_MASK = 0xffffffffffffffffull; // Power (Relay) full mask
+#endif // ESP32
/*********************************************************************************************\
* Constants
@@ -155,19 +160,6 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to
#define MAX_RULE_TIMERS 8 // Max number of rule timers (4 bytes / timer)
#define MAX_RULE_VARS 16 // Max number of rule variables (33 bytes / variable)
-/*
-// Removed from esp8266 core since 20171105
-#define min(a,b) ((a)<(b)?(a):(b))
-#define max(a,b) ((a)>(b)?(a):(b))
-*/
-#define tmin(a,b) ((a)<(b)?(a):(b))
-#define tmax(a,b) ((a)>(b)?(a):(b))
-
-#define STR_HELPER(x) #x
-#ifndef STR
-#define STR(x) STR_HELPER(x)
-#endif
-
//enum ws2812NeopixelbusFeature { NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_3LED, NEO_RGBW, NEO_GRBW }; // Doesn't work
#define NEO_RGB 0 // Neopixel RGB leds
#define NEO_GRB 1 // Neopixel GRB leds
@@ -303,7 +295,8 @@ enum SettingsTextIndex { SET_OTAURL,
SET_BUTTON1, SET_BUTTON2, SET_BUTTON3, SET_BUTTON4, SET_BUTTON5, SET_BUTTON6, SET_BUTTON7, SET_BUTTON8,
SET_BUTTON9, SET_BUTTON10, SET_BUTTON11, SET_BUTTON12, SET_BUTTON13, SET_BUTTON14, SET_BUTTON15, SET_BUTTON16,
SET_MQTT_GRP_TOPIC2, SET_MQTT_GRP_TOPIC3, SET_MQTT_GRP_TOPIC4,
- SET_TEMPLATE_NAME, SET_DEV_GROUP_NAME1, SET_DEV_GROUP_NAME2, SET_DEV_GROUP_NAME3, SET_DEV_GROUP_NAME4,
+ SET_TEMPLATE_NAME,
+ SET_DEV_GROUP_NAME1, SET_DEV_GROUP_NAME2, SET_DEV_GROUP_NAME3, SET_DEV_GROUP_NAME4,
SET_MAX };
enum DevGroupMessageType { DGR_MSGTYP_FULL_STATUS, DGR_MSGTYP_PARTIAL_UPDATE, DGR_MSGTYP_UPDATE, DGR_MSGTYP_UPDATE_MORE_TO_COME, DGR_MSGTYP_UPDATE_DIRECT, DGR_MSGTYPE_UPDATE_COMMAND };
@@ -336,4 +329,21 @@ const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Seri
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };
+enum TasmotaSerialConfig {
+ TS_SERIAL_5N1, TS_SERIAL_6N1, TS_SERIAL_7N1, TS_SERIAL_8N1,
+ TS_SERIAL_5N2, TS_SERIAL_6N2, TS_SERIAL_7N2, TS_SERIAL_8N2,
+ TS_SERIAL_5E1, TS_SERIAL_6E1, TS_SERIAL_7E1, TS_SERIAL_8E1,
+ TS_SERIAL_5E2, TS_SERIAL_6E2, TS_SERIAL_7E2, TS_SERIAL_8E2,
+ TS_SERIAL_5O1, TS_SERIAL_6O1, TS_SERIAL_7O1, TS_SERIAL_8O1,
+ TS_SERIAL_5O2, TS_SERIAL_6O2, TS_SERIAL_7O2, TS_SERIAL_8O2 };
+
+const SerConfu8 kTasmotaSerialConfig[] PROGMEM = {
+ SERIAL_5N1, SERIAL_6N1, SERIAL_7N1, SERIAL_8N1,
+ SERIAL_5N2, SERIAL_6N2, SERIAL_7N2, SERIAL_8N2,
+ SERIAL_5E1, SERIAL_6E1, SERIAL_7E1, SERIAL_8E1,
+ SERIAL_5E2, SERIAL_6E2, SERIAL_7E2, SERIAL_8E2,
+ SERIAL_5O1, SERIAL_6O1, SERIAL_7O1, SERIAL_8O1,
+ SERIAL_5O2, SERIAL_6O2, SERIAL_7O2, SERIAL_8O2
+};
+
#endif // _TASMOTA_H_
diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino
index 6572be777..22e33ce72 100644
--- a/tasmota/tasmota.ino
+++ b/tasmota/tasmota.ino
@@ -32,13 +32,14 @@
// Location specific includes
#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
+#include "tasmota_compat.h"
#include "tasmota_version.h" // Tasmota version information
#include "tasmota.h" // Enumeration used in my_user_config.h
#include "my_user_config.h" // Fixed user configurable options
#ifdef USE_MQTT_TLS
- #include // we need to include before "tasmota_post.h" to take precedence over the BearSSL version in Arduino
+ #include // We need to include before "tasmota_globals.h" to take precedence over the BearSSL version in Arduino
#endif // USE_MQTT_TLS
-#include "tasmota_post.h" // Configuration overrides for all previous includes
+#include "tasmota_globals.h" // Function prototypes and global configuration
#include "i18n.h" // Language support configured by my_user_config.h
#include "tasmota_template.h" // Hardware configuration
@@ -123,7 +124,7 @@ uint8_t mqtt_cmnd_blocked = 0; // Ignore flag for publish command
uint8_t mqtt_cmnd_blocked_reset = 0; // Count down to reset if needed
uint8_t state_250mS = 0; // State 250msecond per second flag
uint8_t latching_relay_pulse = 0; // Latching relay pulse timer
-uint8_t sleep; // Current copy of Settings.sleep
+uint8_t ssleep; // Current copy of Settings.sleep
uint8_t blinkspeed = 1; // LED blink rate
uint8_t pin[GPIO_MAX]; // Possible pin configurations
uint8_t active_device = 1; // Active device in ExecuteCommandPower
@@ -226,7 +227,7 @@ void setup(void)
syslog_level = Settings.syslog_level;
stop_flash_rotate = Settings.flag.stop_flash_rotate; // SetOption12 - Switch between dynamic or fixed slot flash save location
save_data_counter = Settings.save_data;
- sleep = Settings.sleep;
+ ssleep = Settings.sleep;
#ifndef USE_EMULATION
Settings.flag2.emulation = 0;
#else
@@ -259,8 +260,13 @@ void setup(void)
Settings.my_adc0 = ADC0_NONE; // Reset user defined ADC0 disabling sensors
}
if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +4) { // Restarted 6 times
+#ifdef ESP8266
Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic
// Settings.last_module = SONOFF_BASIC;
+#endif // ESP8266
+#ifdef ESP32
+ Settings.module = WEMOS; // Reset module to Wemos
+#endif // ESP32
}
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count);
}
@@ -374,10 +380,10 @@ void loop(void)
if (Settings.flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep
// yield(); // yield == delay(0), delay contains yield, auto yield in loop
- delay(sleep); // https://github.com/esp8266/Arduino/issues/2021
+ delay(ssleep); // https://github.com/esp8266/Arduino/issues/2021
} else {
- if (my_activity < (uint32_t)sleep) {
- delay((uint32_t)sleep - my_activity); // Provide time for background tasks like wifi
+ if (my_activity < (uint32_t)ssleep) {
+ delay((uint32_t)ssleep - my_activity); // Provide time for background tasks like wifi
} else {
if (global_state.wifi_down) {
delay(my_activity /2); // If wifi down and my_activity > setoption36 then force loop delay to 1/3 of my_activity period
@@ -386,7 +392,7 @@ void loop(void)
}
if (!my_activity) { my_activity++; } // We cannot divide by 0
- uint32_t loop_delay = sleep;
+ uint32_t loop_delay = ssleep;
if (!loop_delay) { loop_delay++; } // We cannot divide by 0
uint32_t loops_per_second = 1000 / loop_delay; // We need to keep track of this many loops per second
uint32_t this_cycle_ratio = 100 * my_activity / loop_delay;
diff --git a/tasmota/tasmota_compat.h b/tasmota/tasmota_compat.h
new file mode 100644
index 000000000..97777c566
--- /dev/null
+++ b/tasmota/tasmota_compat.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#ifdef ESP32
+#include
+#define PACKED __attribute((__packed__))
+// Modul
+#undef MODULE
+#define MODULE WEMOS // [Module] Select default model
+#endif
+
+#ifdef ESP8266
+// ESP8266
+#define PACKED
+#define ESP_rtcUserMemoryWrite(offset, data, size) ESP.rtcUserMemoryWrite(offset, data, size)
+#define ESP_rtcUserMemoryRead(offset, data, size) ESP.rtcUserMemoryRead(offset, data, size)
+#define ESP_getResetReason() ESP.getResetReason()
+#define ESP_reset() ESP.reset()
+#define ESP_getBootVersion() ESP.getBootVersion()
+#define ESP_getFlashChipId() ESP.getFlashChipId()
+//
+// we need different ESP_flashRead for ESP32
+//
+#define ESP_flashReadHeader(offset, data, size) ESP.flashRead(offset, data, size)
+#define ESP_flashRead(offset, data, size) ESP.flashRead(offset, data, size)
+//
+// UDP
+#define PortUdp_write(p,n) PortUdp.write(p, n)
+//
+// Serial minimal type to hold the config
+#define SerConfu8 uint8_t
+#endif // ESP32
diff --git a/tasmota/tasmota_post.h b/tasmota/tasmota_configurations.h
similarity index 90%
rename from tasmota/tasmota_post.h
rename to tasmota/tasmota_configurations.h
index 1bba02172..218a83c7d 100644
--- a/tasmota/tasmota_post.h
+++ b/tasmota/tasmota_configurations.h
@@ -1,5 +1,5 @@
/*
- tasmota_post.h - Post header file for Tasmota
+ tasmota_configurations.h - Configurations for Tasmota
Copyright (C) 2020 Theo Arends
@@ -17,73 +17,8 @@
along with this program. If not, see .
*/
-#ifndef _TASMOTA_POST_H_
-#define _TASMOTA_POST_H_
-
-/*********************************************************************************************\
- * Function prototypes
-\*********************************************************************************************/
-
-// Needed for core 2.3.0 compilation (#6721)
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "user_interface.h"
-#ifdef __cplusplus
-}
-#endif
-
-//#ifdef USE_KNX // Enabling this will fail compilation. It has no impact if not used. (20180417)
-#include
-void KNX_CB_Action(message_t const &msg, void *arg);
-//#endif // USE_KNX
-
-void DomoticzTempHumPressureSensor(float temp, float hum, float baro = -1);
-char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0');
-extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end);
-extern "C" void resetPins();
-
-/*********************************************************************************************\
- * Default global defines
-\*********************************************************************************************/
-
-#ifndef ENERGY_OVERTEMP
-#define ENERGY_OVERTEMP 90 // Overtemp in Celsius
-#endif
-
-#ifdef USE_EMULATION_HUE
-#define USE_EMULATION
-#endif
-#ifdef USE_EMULATION_WEMO
-#define USE_EMULATION
-#endif
-#ifdef USE_DEVICE_GROUPS
-#define USE_EMULATION
-#endif
-
-#ifdef USE_MQTT_TLS
- const uint16_t WEB_LOG_SIZE = 2000; // Max number of characters in weblog
-#else
- const uint16_t WEB_LOG_SIZE = 4000; // Max number of characters in weblog
-#endif
-
-#if defined(USE_MQTT_TLS) && defined(ARDUINO_ESP8266_RELEASE_2_3_0)
- #error "TLS is no more supported on Core 2.3.0, use 2.4.2 or higher."
-#endif
-
-#ifndef MODULE
-#define MODULE SONOFF_BASIC // [Module] Select default model
-#endif
-
-#ifdef USE_PWM_DIMMER_REMOTE
-#ifdef USE_PWM_DIMMER
-#ifndef USE_DEVICE_GROUPS
-#define USE_DEVICE_GROUPS
-#endif // USE_DEVICE_GROUPS
-#else // USE_PWM_DIMMER
-#undef USE_PWM_DIMMER_REMOTE
-#endif // USE_PWM_DIMMER
-#endif // USE_PWM_DIMMER_REMOTE
+#ifndef _TASMOTA_CONFIGURATIONS_H_
+#define _TASMOTA_CONFIGURATIONS_H_
/*********************************************************************************************\
* [tasmota-sensors.bin]
@@ -92,8 +27,6 @@ extern "C" void resetPins();
#ifdef FIRMWARE_SENSORS
-#undef CODE_IMAGE
-#define CODE_IMAGE 2
#undef CODE_IMAGE_STR
#define CODE_IMAGE_STR "sensors"
@@ -189,6 +122,8 @@ extern "C" void resetPins();
#define WEMOS_MOTOR_V1_ADDR 0x30 // Default I2C address 0x30
#define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency
//#define USE_HDC1080 // Enable HDC1080 temperature/humidity sensor
+#define USE_IAQ // [I2cDriver46] Enable iAQ-core air quality sensor (I2C address 0x5a) (+0k6 code)
+#define USE_AS3935 // [I2cDriver48] Enable AS3935 Franklin Lightning Sensor (I2C address 0x03) (+5k4 code)
#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
@@ -257,8 +192,6 @@ extern "C" void resetPins();
#ifdef FIRMWARE_KNX_NO_EMULATION
-#undef CODE_IMAGE
-#define CODE_IMAGE 3
#undef CODE_IMAGE_STR
#define CODE_IMAGE_STR "knx"
@@ -282,8 +215,6 @@ extern "C" void resetPins();
#ifdef FIRMWARE_DISPLAYS
-#undef CODE_IMAGE
-#define CODE_IMAGE 5
#undef CODE_IMAGE_STR
#define CODE_IMAGE_STR "display"
@@ -332,6 +263,7 @@ extern "C" void resetPins();
#define USE_DISPLAY_LCD // [DisplayModel 1] Enable Lcd display (I2C addresses 0x27 and 0x3F) (+6k code)
#define USE_DISPLAY_SSD1306 // [DisplayModel 2] Enable SSD1306 Oled 128x64 display (I2C addresses 0x3C and 0x3D) (+16k code)
#define USE_DISPLAY_MATRIX // [DisplayModel 3] Enable 8x8 Matrix display (I2C adresseses see below) (+11k code)
+ #define USE_DISPLAY_SEVENSEG // [DisplayModel 11] [I2cDriver47] Enable sevenseg display (I2C addresses 0x70 - 0x77) (<+11k code)
#define USE_DISPLAY_SH1106 // [DisplayModel 7] Enable SH1106 Oled 128x64 display (I2C addresses 0x3C and 0x3D)
#define USE_SPI // Hardware SPI using GPIO12(MISO), GPIO13(MOSI) and GPIO14(CLK) in addition to two user selectable GPIOs(CS and DC)
@@ -355,8 +287,6 @@ extern "C" void resetPins();
#ifdef FIRMWARE_IR
-#undef CODE_IMAGE
-#define CODE_IMAGE 6
#undef CODE_IMAGE_STR
#define CODE_IMAGE_STR "ir"
@@ -462,8 +392,6 @@ extern "C" void resetPins();
#ifdef FIRMWARE_LITE
-#undef CODE_IMAGE
-#define CODE_IMAGE 4
#undef CODE_IMAGE_STR
#define CODE_IMAGE_STR "lite"
@@ -579,8 +507,6 @@ extern "C" void resetPins();
#ifdef FIRMWARE_MINIMAL
-#undef CODE_IMAGE
-#define CODE_IMAGE 1
#undef CODE_IMAGE_STR
#define CODE_IMAGE_STR "minimal"
@@ -692,95 +618,4 @@ extern "C" void resetPins();
#undef USE_DEBUG_DRIVER // Disable debug code
#endif // FIRMWARE_MINIMAL
-/*********************************************************************************************\
- * Mandatory defines satisfying possible disabled defines
-\*********************************************************************************************/
-
- // See https://github.com/esp8266/Arduino/pull/4889
-#undef NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions)
-
-#ifndef USE_SONOFF_RF
-#undef USE_RF_FLASH // Disable RF firmware flash when SOnoff Rf is disabled
-#endif
-
-#ifndef SWITCH_MODE
-#define SWITCH_MODE TOGGLE // TOGGLE, FOLLOW or FOLLOW_INV (the wall switch state)
-#endif
-
-#ifndef STARTING_OFFSET // NOVA SDS parameter used in settings
-#define STARTING_OFFSET 30
-#endif
-
-#ifndef MQTT_FINGERPRINT1
-// Set an all-zeros default fingerprint to activate auto-learning on first connection (AWS IoT)
-#define MQTT_FINGERPRINT1 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
-#endif
-
-#ifndef MQTT_FINGERPRINT2
-#define MQTT_FINGERPRINT2 "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07"
-#endif
-
-#ifndef WS2812_LEDS
-#define WS2812_LEDS 30 // [Pixels] Number of LEDs
-#endif
-
-#ifndef MQTT_MAX_PACKET_SIZE
-#define MQTT_MAX_PACKET_SIZE 1200 // Bytes
-#endif
-#ifndef MQTT_KEEPALIVE
-#define MQTT_KEEPALIVE 30 // Seconds
-#endif
-#ifndef MQTT_TIMEOUT
-#define MQTT_TIMEOUT 10000 // milli seconds
-#endif
-#ifndef MQTT_CLEAN_SESSION
-#define MQTT_CLEAN_SESSION 1 // 0 = No clean session, 1 = Clean session (default)
-#endif
-
-#ifndef MESSZ
-//#define MESSZ 1040 // Max number of characters in JSON message string (Hass discovery and nice MQTT_MAX_PACKET_SIZE = 1200)
-#define MESSZ (MQTT_MAX_PACKET_SIZE -TOPSZ -7) // Max number of characters in JSON message string
-#endif
-
-//#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0)
-#ifndef ARDUINO_ESP8266_RELEASE
-#define ARDUINO_ESP8266_RELEASE "STAGE"
-#endif
-
-#ifdef ARDUINO_ESP8266_RELEASE_2_3_0 // Disable not supported features in core 2.3.0
-#undef USE_MQTT_TLS_CA_CERT
-#endif
-
-#ifdef USE_DEVICE_GROUPS
-#define SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, ...) _SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, __VA_ARGS__, 0)
-#define SendLocalDeviceGroupMessage(REQUEST_TYPE, ...) _SendDeviceGroupMessage(0, REQUEST_TYPE, __VA_ARGS__, 0)
-#define DEVICE_GROUP_MESSAGE "M-TASMOTA_DGR/"
-const char kDeviceGroupMessage[] PROGMEM = DEVICE_GROUP_MESSAGE;
-uint8_t device_group_count = 1;
-#endif // USE_DEVICE_GROUPS
-
-#ifdef DEBUG_TASMOTA_CORE
-#define DEBUG_CORE_LOG(...) AddLog_Debug(__VA_ARGS__)
-#else
-#define DEBUG_CORE_LOG(...)
-#endif
-
-#ifdef DEBUG_TASMOTA_DRIVER
-#define DEBUG_DRIVER_LOG(...) AddLog_Debug(__VA_ARGS__)
-#else
-#define DEBUG_DRIVER_LOG(...)
-#endif
-
-#ifdef DEBUG_TASMOTA_SENSOR
-#define DEBUG_SENSOR_LOG(...) AddLog_Debug(__VA_ARGS__)
-#else
-#define DEBUG_SENSOR_LOG(...)
-#endif
-
-#ifdef DEBUG_TASMOTA_TRACE
-#define DEBUG_TRACE_LOG(...) AddLog_Debug(__VA_ARGS__)
-#else
-#define DEBUG_TRACE_LOG(...)
-#endif
-
-#endif // _TASMOTA_POST_H_
+#endif // _TASMOTA_CONFIGURATIONS_H_
diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h
new file mode 100644
index 000000000..d05db0efd
--- /dev/null
+++ b/tasmota/tasmota_globals.h
@@ -0,0 +1,335 @@
+/*
+ tasmota_globals.h - Function prototypes and global configurations for Tasmota
+
+ Copyright (C) 2020 Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef _TASMOTA_GLOBALS_H_
+#define _TASMOTA_GLOBALS_H_
+
+/*********************************************************************************************\
+ * Function prototypes
+\*********************************************************************************************/
+
+// Needed for core 2.3.0 compilation (#6721)
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "user_interface.h"
+#ifdef __cplusplus
+}
+#endif
+
+//#ifdef USE_KNX // Enabling this will fail compilation. It has no impact if not used. (20180417)
+#include
+void KNX_CB_Action(message_t const &msg, void *arg);
+//#endif // USE_KNX
+
+void DomoticzTempHumPressureSensor(float temp, float hum, float baro = -1);
+char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, char inbetween = '\0');
+extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end);
+extern "C" void resetPins();
+
+/*********************************************************************************************\
+ * Preconfigured configurations
+\*********************************************************************************************/
+
+#include "tasmota_configurations.h" // Preconfigured configurations
+
+/*********************************************************************************************\
+ * Mandatory defines satisfying disabled defines
+\*********************************************************************************************/
+
+#ifndef MODULE
+#define MODULE SONOFF_BASIC // [Module] Select default model
+#endif
+
+#ifdef USE_EMULATION_HUE
+#define USE_EMULATION
+#endif
+#ifdef USE_EMULATION_WEMO
+#define USE_EMULATION
+#endif
+#ifdef USE_DEVICE_GROUPS
+#define USE_EMULATION
+#endif
+ // See https://github.com/esp8266/Arduino/pull/4889
+#undef NO_EXTRA_4K_HEAP // Allocate 4k heap for WPS in ESP8166/Arduino core v2.4.2 (was always allocated in previous versions)
+
+#ifndef USE_SONOFF_RF
+#undef USE_RF_FLASH // Disable RF firmware flash when Sonoff Rf is disabled
+#endif
+
+#ifndef SWITCH_MODE
+#define SWITCH_MODE TOGGLE // TOGGLE, FOLLOW or FOLLOW_INV (the wall switch state)
+#endif
+
+#ifndef MQTT_FINGERPRINT1
+// Set an all-zeros default fingerprint to activate auto-learning on first connection (AWS IoT)
+#define MQTT_FINGERPRINT1 "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
+#endif
+#ifndef MQTT_FINGERPRINT2
+#define MQTT_FINGERPRINT2 "A5 02 FF 13 99 9F 8B 39 8E F1 83 4F 11 23 65 0B 32 36 FC 07"
+#endif
+
+#ifndef WS2812_LEDS
+#define WS2812_LEDS 30 // [Pixels] Number of LEDs
+#endif
+
+#ifdef USE_MQTT_TLS
+ const uint16_t WEB_LOG_SIZE = 2000; // Max number of characters in weblog
+#else
+ const uint16_t WEB_LOG_SIZE = 4000; // Max number of characters in weblog
+#endif
+
+#if defined(USE_MQTT_TLS) && defined(ARDUINO_ESP8266_RELEASE_2_3_0)
+ #error "TLS is no more supported on Core 2.3.0, use 2.4.2 or higher."
+#endif
+
+#ifndef MQTT_MAX_PACKET_SIZE
+#define MQTT_MAX_PACKET_SIZE 1200 // Bytes
+#endif
+#ifndef MQTT_KEEPALIVE
+#define MQTT_KEEPALIVE 30 // Seconds
+#endif
+#ifndef MQTT_TIMEOUT
+#define MQTT_TIMEOUT 10000 // milli seconds
+#endif
+#ifndef MQTT_CLEAN_SESSION
+#define MQTT_CLEAN_SESSION 1 // 0 = No clean session, 1 = Clean session (default)
+#endif
+
+#ifndef MESSZ
+//#define MESSZ 1040 // Max number of characters in JSON message string (Hass discovery and nice MQTT_MAX_PACKET_SIZE = 1200)
+#define MESSZ (MQTT_MAX_PACKET_SIZE -TOPSZ -7) // Max number of characters in JSON message string
+#endif
+
+#ifndef ARDUINO_ESP8266_RELEASE
+#define ARDUINO_ESP8266_RELEASE "STAGE"
+#endif
+
+#ifdef USE_PWM_DIMMER_REMOTE
+#ifdef USE_PWM_DIMMER
+#ifndef USE_DEVICE_GROUPS
+#define USE_DEVICE_GROUPS
+#endif // USE_DEVICE_GROUPS
+#else // USE_PWM_DIMMER
+#undef USE_PWM_DIMMER_REMOTE
+#endif // USE_PWM_DIMMER
+#endif // USE_PWM_DIMMER_REMOTE
+
+#ifndef DOMOTICZ_UPDATE_TIMER
+#define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds) (Optional)
+#endif
+
+#ifndef EMULATION
+#define EMULATION EMUL_NONE // [Emulation] Select Belkin WeMo (single relay/light) or Hue Bridge emulation (multi relay/light) (EMUL_NONE, EMUL_WEMO or EMUL_HUE)
+#endif
+
+#ifndef MTX_ADDRESS1 // Add Display Support for up to eigth Matrices
+#define MTX_ADDRESS1 0
+#endif
+#ifndef MTX_ADDRESS2
+#define MTX_ADDRESS2 0
+#endif
+#ifndef MTX_ADDRESS3
+#define MTX_ADDRESS3 0
+#endif
+#ifndef MTX_ADDRESS4
+#define MTX_ADDRESS4 0
+#endif
+#ifndef MTX_ADDRESS5
+#define MTX_ADDRESS5 0
+#endif
+#ifndef MTX_ADDRESS6
+#define MTX_ADDRESS6 0
+#endif
+#ifndef MTX_ADDRESS7
+#define MTX_ADDRESS7 0
+#endif
+#ifndef MTX_ADDRESS8
+#define MTX_ADDRESS8 0
+#endif
+
+#ifndef HOME_ASSISTANT_DISCOVERY_ENABLE
+#define HOME_ASSISTANT_DISCOVERY_ENABLE 0
+#endif
+
+#ifndef LATITUDE
+#define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset
+#endif
+#ifndef LONGITUDE
+#define LONGITUDE 2.294442 // [Longitude] Your location to be used with sunrise and sunset
+#endif
+
+#ifndef IR_RCV_MIN_UNKNOWN_SIZE
+#define IR_RCV_MIN_UNKNOWN_SIZE 6 // Set the smallest sized "UNKNOWN" message packets we actually care about (default 6, max 255)
+#endif
+
+#ifndef ENERGY_OVERTEMP
+#define ENERGY_OVERTEMP 90 // Overtemp in Celsius
+#endif
+
+#ifndef DEFAULT_DIMMER_MAX
+#define DEFAULT_DIMMER_MAX 100
+#endif
+#ifndef DEFAULT_DIMMER_MIN
+#define DEFAULT_DIMMER_MIN 0
+#endif
+#ifndef DEFAULT_LIGHT_DIMMER
+#define DEFAULT_LIGHT_DIMMER 10
+#endif
+#ifndef DEFAULT_LIGHT_COMPONENT
+#define DEFAULT_LIGHT_COMPONENT 255
+#endif
+
+#ifndef CORS_ENABLED_ALL
+#define CORS_ENABLED_ALL "*"
+#endif
+
+#ifndef WORKING_PERIOD
+#define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes
+#endif
+#ifndef STARTING_OFFSET
+#define STARTING_OFFSET 30 // NOVA SDS parameter used in settings
+#endif
+
+/*********************************************************************************************\
+ * UserConfig related parameters
+\*********************************************************************************************/
+
+#ifndef COLOR_TEXT
+#define COLOR_TEXT "#000" // Global text color - Black
+#endif
+#ifndef COLOR_BACKGROUND
+#define COLOR_BACKGROUND "#fff" // Global background color - White
+#endif
+#ifndef COLOR_FORM
+#define COLOR_FORM "#f2f2f2" // Form background color - Greyish
+#endif
+#ifndef COLOR_INPUT_TEXT
+#define COLOR_INPUT_TEXT "#000" // Input text color - Black
+#endif
+#ifndef COLOR_INPUT
+#define COLOR_INPUT "#fff" // Input background color - White
+#endif
+#ifndef COLOR_CONSOLE_TEXT
+#define COLOR_CONSOLE_TEXT "#000" // Console text color - Black
+#endif
+#ifndef COLOR_CONSOLE
+#define COLOR_CONSOLE "#fff" // Console background color - White
+#endif
+#ifndef COLOR_TEXT_WARNING
+#define COLOR_TEXT_WARNING "#f00" // Warning text color - Red
+#endif
+#ifndef COLOR_TEXT_SUCCESS
+#define COLOR_TEXT_SUCCESS "#008000" // Success text color - Green
+#endif
+#ifndef COLOR_BUTTON_TEXT
+#define COLOR_BUTTON_TEXT "#fff" // Button text color - White
+#endif
+#ifndef COLOR_BUTTON
+#define COLOR_BUTTON "#1fa3ec" // Button color - Blueish
+#endif
+#ifndef COLOR_BUTTON_HOVER
+#define COLOR_BUTTON_HOVER "#0e70a4" // Button color when hovered over - Darker blueish
+#endif
+#ifndef COLOR_BUTTON_RESET
+#define COLOR_BUTTON_RESET "#d43535" // Restart/Reset/Delete button color - Redish
+#endif
+#ifndef COLOR_BUTTON_RESET_HOVER
+#define COLOR_BUTTON_RESET_HOVER "#931f1f" // Restart/Reset/Delete button color when hovered over - Darker redish
+#endif
+#ifndef COLOR_BUTTON_SAVE
+#define COLOR_BUTTON_SAVE "#47c266" // Save button color - Greenish
+#endif
+#ifndef COLOR_BUTTON_SAVE_HOVER
+#define COLOR_BUTTON_SAVE_HOVER "#5aaf6f" // Save button color when hovered over - Darker greenish
+#endif
+#ifndef COLOR_TIMER_TAB_TEXT
+#define COLOR_TIMER_TAB_TEXT "#fff" // Config timer tab text color - White
+#endif
+#ifndef COLOR_TIMER_TAB_BACKGROUND
+#define COLOR_TIMER_TAB_BACKGROUND "#999" // Config timer tab background color - Light grey
+#endif
+#ifndef COLOR_TITLE_TEXT
+#define COLOR_TITLE_TEXT COLOR_TEXT // Title text color defaults to global text color either dark or light
+#endif
+
+enum WebColors {
+ COL_TEXT, COL_BACKGROUND, COL_FORM,
+ COL_INPUT_TEXT, COL_INPUT, COL_CONSOLE_TEXT, COL_CONSOLE,
+ COL_TEXT_WARNING, COL_TEXT_SUCCESS,
+ COL_BUTTON_TEXT, COL_BUTTON, COL_BUTTON_HOVER, COL_BUTTON_RESET, COL_BUTTON_RESET_HOVER, COL_BUTTON_SAVE, COL_BUTTON_SAVE_HOVER,
+ COL_TIMER_TAB_TEXT, COL_TIMER_TAB_BACKGROUND, COL_TITLE,
+ COL_LAST };
+
+const char kWebColors[] PROGMEM =
+ COLOR_TEXT "|" COLOR_BACKGROUND "|" COLOR_FORM "|"
+ COLOR_INPUT_TEXT "|" COLOR_INPUT "|" COLOR_CONSOLE_TEXT "|" COLOR_CONSOLE "|"
+ COLOR_TEXT_WARNING "|" COLOR_TEXT_SUCCESS "|"
+ COLOR_BUTTON_TEXT "|" COLOR_BUTTON "|" COLOR_BUTTON_HOVER "|" COLOR_BUTTON_RESET "|" COLOR_BUTTON_RESET_HOVER "|" COLOR_BUTTON_SAVE "|" COLOR_BUTTON_SAVE_HOVER "|"
+ COLOR_TIMER_TAB_TEXT "|" COLOR_TIMER_TAB_BACKGROUND "|" COLOR_TITLE_TEXT;
+
+/*********************************************************************************************\
+ * Macros
+\*********************************************************************************************/
+
+/*
+// Removed from esp8266 core since 20171105
+#define min(a,b) ((a)<(b)?(a):(b))
+#define max(a,b) ((a)>(b)?(a):(b))
+*/
+#define tmin(a,b) ((a)<(b)?(a):(b))
+#define tmax(a,b) ((a)>(b)?(a):(b))
+
+#define STR_HELPER(x) #x
+#ifndef STR
+#define STR(x) STR_HELPER(x)
+#endif
+
+#ifdef USE_DEVICE_GROUPS
+#define SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, ...) _SendDeviceGroupMessage(DEVICE_INDEX, REQUEST_TYPE, __VA_ARGS__, 0)
+#define SendLocalDeviceGroupMessage(REQUEST_TYPE, ...) _SendDeviceGroupMessage(0, REQUEST_TYPE, __VA_ARGS__, 0)
+#define DEVICE_GROUP_MESSAGE "M-TASMOTA_DGR/"
+const char kDeviceGroupMessage[] PROGMEM = DEVICE_GROUP_MESSAGE;
+uint8_t device_group_count = 1;
+#endif // USE_DEVICE_GROUPS
+
+#ifdef DEBUG_TASMOTA_CORE
+#define DEBUG_CORE_LOG(...) AddLog_Debug(__VA_ARGS__)
+#else
+#define DEBUG_CORE_LOG(...)
+#endif
+#ifdef DEBUG_TASMOTA_DRIVER
+#define DEBUG_DRIVER_LOG(...) AddLog_Debug(__VA_ARGS__)
+#else
+#define DEBUG_DRIVER_LOG(...)
+#endif
+#ifdef DEBUG_TASMOTA_SENSOR
+#define DEBUG_SENSOR_LOG(...) AddLog_Debug(__VA_ARGS__)
+#else
+#define DEBUG_SENSOR_LOG(...)
+#endif
+#ifdef DEBUG_TASMOTA_TRACE
+#define DEBUG_TRACE_LOG(...) AddLog_Debug(__VA_ARGS__)
+#else
+#define DEBUG_TRACE_LOG(...)
+#endif
+
+/*********************************************************************************************/
+
+#endif // _TASMOTA_GLOBALS_H_
diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h
index 5ad118377..83db4bace 100644
--- a/tasmota/tasmota_template.h
+++ b/tasmota/tasmota_template.h
@@ -227,6 +227,7 @@ enum UserSelectablePins {
GPIO_CC1101_GDO2, // CC1101 pin for RX
GPIO_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor
GPIO_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX
+ GPIO_AS3935,
GPIO_SENSOR_END };
// Programmer selectable GPIO functionality
@@ -313,7 +314,8 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_LE01MR_RX "|" D_SENSOR_LE01MR_TX "|"
D_SENSOR_CC1101_GDO0 "|" D_SENSOR_CC1101_GDO2 "|"
D_SENSOR_HRXL_RX "|"
- D_SENSOR_ELECTRIQ_MOODL
+ D_SENSOR_ELECTRIQ_MOODL "|"
+ D_SENSOR_AS3935
;
const char kSensorNamesFixed[] PROGMEM =
@@ -658,6 +660,9 @@ const uint8_t kGpioNiceList[] PROGMEM = {
#ifdef USE_HRXL
GPIO_HRXL_RX,
#endif
+#ifdef USE_AS3935
+ GPIO_AS3935,
+#endif
};
/********************************************************************************************/
@@ -694,11 +699,26 @@ const char kAdc0Names[] PROGMEM =
/********************************************************************************************/
+#ifdef ESP8266
+
#define MAX_GPIO_PIN 17 // Number of supported GPIO
#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11)
const char PINS_WEMOS[] PROGMEM = "D3TXD4RXD2D1flashcFLFLolD6D7D5D8D0A0";
+#else // ESP32
+
+// esp32 has more pins
+#define USER_MODULE 255
+#define MAX_GPIO_PIN 44 // Number of supported GPIO
+#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11)
+
+const char PINS_WEMOS[] PROGMEM = "00010203040506070809101112131415161718192021222324252627282930313233343536373839";
+
+#endif // ESP8266
+
+/********************************************************************************************/
+
typedef struct MYIO {
uint8_t io[MAX_GPIO_PIN];
} myio;
@@ -732,6 +752,8 @@ typedef struct MYTMPLT {
/********************************************************************************************/
+#ifdef ESP8266
+
// Supported hardware modules
enum SupportedModules {
SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH,
@@ -2223,4 +2245,10 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
}
};
+#endif // ESP8266
+
+#ifdef ESP32
+#include "tasmota_template_ESP32.h"
+#endif // ESP32
+
#endif // _TASMOTA_TEMPLATE_H_
diff --git a/tasmota/tasmota_template_ESP32.h b/tasmota/tasmota_template_ESP32.h
new file mode 100644
index 000000000..3f1b2b8c6
--- /dev/null
+++ b/tasmota/tasmota_template_ESP32.h
@@ -0,0 +1,155 @@
+/*
+ tasmota_template_ESP32.h - template settings for Tasmota
+
+ Copyright (C) 2020 Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef _TASMOTA_TEMPLATE_ESP32_H_
+#define _TASMOTA_TEMPLATE_ESP32_H_
+
+#ifdef ESP32
+
+// mqtt
+#undef MQTT_LIBRARY_TYPE
+#define MQTT_LIBRARY_TYPE MQTT_PUBSUBCLIENT
+// Hardware has no ESP32
+#undef USE_TUYA_DIMMER
+#undef USE_PWM_DIMMER
+#undef USE_EXS_DIMMER
+#undef USE_ARMTRONIX_DIMMERS
+#undef USE_SONOFF_RF
+#undef USE_SONOFF_SC
+#undef USE_SONOFF_IFAN
+#undef USE_SONOFF_L1
+#undef USE_SONOFF_D1
+#undef USE_RF_FLASH
+// not ported
+#undef USE_DISCOVERY
+#undef USE_ADC_VCC // Needs to be ported
+#undef USE_DEEPSLEEP
+#undef USE_MY92X1
+#undef USE_TUYA_MCU
+#undef USE_I2C
+#undef USE_PS_16_DZ
+
+/********************************************************************************************/
+// Supported hardware modules
+enum SupportedModules {
+ WEMOS,
+ ESP32_CAM,
+ MAXMODULE
+};
+
+const char kModuleNames[] PROGMEM =
+ "WeMos D1 ESP32|ESP32 CAM|"
+ ;
+
+// Default module settings
+const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {
+ WEMOS,
+ ESP32_CAM
+};
+
+const mytmplt kModules[MAXMODULE] PROGMEM = {
+ { // "WeMos D1 ESP32", // Any ESP32 device like WeMos and NodeMCU hardware (ESP32)
+ GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
+ GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
+ GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0
+ GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2
+ GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER
+ GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK
+ 0, //6
+ 0, //7
+ 0, //8
+ 0, //9
+ 0, //10
+ 0, //11
+ GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.)
+ GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
+ GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
+ GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.)
+ GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT
+ GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180
+ GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7
+ GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0
+ 0, //20
+ 0, //21 IO GPIO21, VSPIHD, EMAC_TX_EN
+ GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1
+ GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE
+ 0, //24
+ GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0
+ GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1
+ GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV
+ 0, //28
+ 0, //29
+ 0, //30
+ 0, //31
+ GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9
+ GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8
+ GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4
+ GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5
+ GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0
+ 0, //37 NO PULLUP
+ 0, //38 NO PULLUP
+ GPIO_USER //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
+ },
+ { //"ESP32 CAM",
+ GPIO_USER, //0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK
+ GPIO_USER, //1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2
+ GPIO_USER, //2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0
+ GPIO_USER, //3 IO RXD0 GPIO3, U0RXD, CLK_OUT2
+ GPIO_USER, //4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER
+ GPIO_USER, //5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK
+ 0, //6
+ 0, //7
+ 0, //8
+ 0, //9
+ 0, //10
+ 0, //11
+ GPIO_USER, //12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.)
+ GPIO_USER, //13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
+ GPIO_USER, //14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
+ GPIO_USER, //15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.)
+ GPIO_USER, //16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT
+ GPIO_USER, //17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180
+ GPIO_USER, //18 IO GPIO18, VSPICLK, HS1_DATA7
+ GPIO_USER, //19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0
+ 0, //20
+ 0, //21 IO GPIO21, VSPIHD, EMAC_TX_EN
+ GPIO_USER, //22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1
+ GPIO_USER, //23 IO GPIO23, VSPID, HS1_STROBE
+ 0, //24
+ GPIO_USER, //25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0
+ GPIO_USER, //26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1
+ GPIO_USER, //27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV
+ 0, //28
+ 0, //29
+ 0, //30
+ 0, //31
+ GPIO_USER, //32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9
+ GPIO_USER, //33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8
+ GPIO_USER, //34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4
+ GPIO_USER, //35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5
+ GPIO_USER, //36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0
+ 0, //37 NO PULLUP
+ 0, //38 NO PULLUP
+ GPIO_USER //39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3
+ }
+};
+
+#endif // ESP32
+
+#endif // _TASMOTA_TEMPLATE_ESP32_H_
diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino
index 1a45434a3..f50f41d3f 100644
--- a/tasmota/xdrv_01_webserver.ino
+++ b/tasmota/xdrv_01_webserver.ino
@@ -48,7 +48,7 @@ enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTASLAVE };
static const char * HEADER_KEYS[] = { "User-Agent", };
-const char HTTP_HEADER[] PROGMEM =
+const char HTTP_HEADER1[] PROGMEM =
""
""
""
@@ -848,7 +848,7 @@ void WSContentStart_P(const char* title, bool auth)
if (title != nullptr) {
char ctitle[strlen_P(title) +1];
strcpy_P(ctitle, title); // Get title from flash to RAM
- WSContentSend_P(HTTP_HEADER, SettingsText(SET_FRIENDLYNAME1), ctitle);
+ WSContentSend_P(HTTP_HEADER1, SettingsText(SET_FRIENDLYNAME1), ctitle);
}
}
@@ -1266,7 +1266,7 @@ bool HandleRootStatusRefresh(void)
#ifdef USE_SHUTTER
int32_t ShutterWebButton;
if (ShutterWebButton = IsShutterWebButton(device)) {
- snprintf_P(svalue, sizeof(svalue), PSTR("ShutterPosition%d %s"), abs(ShutterWebButton), (ShutterWebButton>0) ? PSTR(D_CMND_SHUTTER_TOGGLEUP) : PSTR(D_CMND_SHUTTER_TOGGLEDOWN));
+ snprintf_P(svalue, sizeof(svalue), PSTR("ShutterPosition%d %s"), abs(ShutterWebButton), (ShutterWebButton>0) ? PSTR(D_CMND_SHUTTER_STOPOPEN) : PSTR(D_CMND_SHUTTER_STOPCLOSE));
ExecuteWebCommand(svalue, SRC_WEBGUI);
} else {
#endif // USE_SHUTTER
@@ -2175,7 +2175,7 @@ void HandleInformation(void)
WSContentSend_P(PSTR("}1}2 ")); // Empty line
WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d"), ESP.getChipId());
- WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP.getFlashChipId());
+ WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP_getFlashChipId());
WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%dkB"), ESP.getFlashChipRealSize() / 1024);
WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%dkB"), ESP.getFlashChipSize() / 1024);
WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%dkB"), ESP.getSketchSize() / 1024);
diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino
index 9b83a6879..240a09417 100644
--- a/tasmota/xdrv_04_light.ino
+++ b/tasmota/xdrv_04_light.ino
@@ -950,17 +950,21 @@ public:
// only if non-multi channel
// We apply dimmer in priority to RGB
uint8_t bri = _state->DimmerToBri(Settings.light_dimmer);
+
+ // The default values are #FFFFFFFFFF, in this case we avoid setting all channels
+ // at the same time, see #6534 and #8120
+ if ((DEFAULT_LIGHT_COMPONENT == Settings.light_color[0]) &&
+ (DEFAULT_LIGHT_COMPONENT == Settings.light_color[1]) &&
+ (DEFAULT_LIGHT_COMPONENT == Settings.light_color[2]) &&
+ (DEFAULT_LIGHT_COMPONENT == Settings.light_color[3]) &&
+ (DEFAULT_LIGHT_COMPONENT == Settings.light_color[4]) &&
+ (DEFAULT_LIGHT_DIMMER == Settings.light_dimmer) ) {
+ _state->setBriCT(bri);
+ _state->setBriRGB(bri);
+ _state->setColorMode(LCM_RGB);
+ }
+
if (Settings.light_color[0] + Settings.light_color[1] + Settings.light_color[2] > 0) {
- // The default values are #FFFFFFFFFF, in this case we avoid setting all channels
- // at the same time, see #6534
- if ( (DEFAULT_LIGHT_COMPONENT == Settings.light_color[0]) &&
- (DEFAULT_LIGHT_COMPONENT == Settings.light_color[1]) &&
- (DEFAULT_LIGHT_COMPONENT == Settings.light_color[2]) &&
- (DEFAULT_LIGHT_COMPONENT == Settings.light_color[3]) &&
- (DEFAULT_LIGHT_COMPONENT == Settings.light_color[4]) &&
- (DEFAULT_LIGHT_DIMMER == Settings.light_dimmer) ) {
- _state->setColorMode(LCM_RGB);
- }
_state->setBriRGB(bri);
} else {
_state->setBriCT(bri);
@@ -1216,6 +1220,7 @@ bool LightModuleInit(void)
if (XlgtCall(FUNC_MODULE_INIT)) {
// serviced
}
+#ifdef ESP8266
else if (SONOFF_BN == my_module_type) { // PWM Single color led (White)
light_type = LT_PWM1;
}
@@ -1234,6 +1239,7 @@ bool LightModuleInit(void)
}
light_type = LT_PWM2;
}
+#endif // ESP8266
if (light_type > LT_BASIC) {
devices_present++;
@@ -1701,12 +1707,12 @@ void LightAnimate(void)
// or set a maximum of PWM_MAX_SLEEP if light is on or Fade is running
if (Light.power || Light.fade_running) {
if (Settings.sleep > PWM_MAX_SLEEP) {
- sleep = PWM_MAX_SLEEP; // set a maxumum value of 50 milliseconds to ensure that animations are smooth
+ ssleep = PWM_MAX_SLEEP; // set a maxumum value of 50 milliseconds to ensure that animations are smooth
} else {
- sleep = Settings.sleep; // or keep the current sleep if it's lower than 50
+ ssleep = Settings.sleep; // or keep the current sleep if it's lower than 50
}
} else {
- sleep = Settings.sleep;
+ ssleep = Settings.sleep;
}
if (!Light.power) { // All channels powered off
@@ -1891,11 +1897,12 @@ void LightAnimate(void)
bool isChannelGammaCorrected(uint32_t channel) {
if (!Settings.light_correction) { return false; } // Gamma correction not activated
if (channel >= Light.subtype) { return false; } // Out of range
-
+#ifdef ESP8266
if (PHILIPS == my_module_type) {
if ((LST_COLDWARM == Light.subtype) && (1 == channel)) { return false; } // PMW reserved for CT
if ((LST_RGBCW == Light.subtype) && (4 == channel)) { return false; } // PMW reserved for CT
}
+#endif // ESP8266
return true;
}
@@ -2070,6 +2077,7 @@ void calcGammaBulbs(uint16_t cur_col_10[5]) {
uint16_t white_bri10 = cur_col_10[cw0] + cur_col_10[cw1]; // cumulated brightness
uint16_t white_bri10_1023 = (white_bri10 > 1023) ? 1023 : white_bri10; // max 1023
+#ifdef ESP8266
if (PHILIPS == my_module_type) { // channel 1 is the color tone, mapped to cold channel (0..255)
// Xiaomi Philips bulbs follow a different scheme:
cur_col_10[cw1] = light_state.getCT10bits();
@@ -2079,7 +2087,9 @@ void calcGammaBulbs(uint16_t cur_col_10[5]) {
} else {
cur_col_10[cw0] = white_bri10_1023; // no gamma, extend to 10 bits
}
- } else if (Settings.light_correction) {
+ } else
+#endif // ESP8266
+ if (Settings.light_correction) {
// if sum of both channels is > 255, then channels are probably uncorrelated
if (white_bri10 <= 1031) { // take a margin of 8 above 1023 to account for rounding errors
// we calculate the gamma corrected sum of CW + WW
@@ -2631,7 +2641,9 @@ void CmndDimmerRange(void)
Settings.dimmer_hw_min = parm[1];
Settings.dimmer_hw_max = parm[0];
}
+#ifdef ESP8266
if (PWM_DIMMER != my_module_type) restart_flag = 2;
+#endif // ESP8266
}
Response_P(PSTR("{\"" D_CMND_DIMMER_RANGE "\":{\"Min\":%d,\"Max\":%d}}"), Settings.dimmer_hw_min, Settings.dimmer_hw_max);
}
diff --git a/tasmota/xdrv_06_snfbridge.ino b/tasmota/xdrv_06_snfbridge.ino
index c8e9db67e..68365fceb 100644
--- a/tasmota/xdrv_06_snfbridge.ino
+++ b/tasmota/xdrv_06_snfbridge.ino
@@ -565,6 +565,7 @@ bool Xdrv06(uint8_t function)
{
bool result = false;
+#ifdef ESP8266
if (SONOFF_BRIDGE == my_module_type) {
switch (function) {
case FUNC_SERIAL:
@@ -582,6 +583,7 @@ bool Xdrv06(uint8_t function)
break;
}
}
+#endif // ESP8266
return result;
}
diff --git a/tasmota/xdrv_11_knx.ino b/tasmota/xdrv_11_knx.ino
index d0198e389..b8177c1ad 100644
--- a/tasmota/xdrv_11_knx.ino
+++ b/tasmota/xdrv_11_knx.ino
@@ -556,8 +556,7 @@ void KNX_CB_Action(message_t const &msg, void *arg)
if (msg.data_len == 1) {
// COMMAND
- tempchar[0] = msg.data[0];
- tempchar[1] = '\0';
+ sprintf(tempchar,"%d",msg.data[0]);
} else {
// VALUE
float tempvar = knx.data_to_2byte_float(msg.data);
diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino
index e3ba4670d..3794ba072 100644
--- a/tasmota/xdrv_12_home_assistant.ino
+++ b/tasmota/xdrv_12_home_assistant.ino
@@ -213,7 +213,11 @@ void HAssAnnounceRelayLight(void)
TryResponseAppend_P(HASS_DISCOVER_DEVICE_INFO_SHORT, unique_id, ESP.getChipId());
#ifdef USE_LIGHT
- if (is_light || PWM_DIMMER == my_module_type)
+ if (is_light
+#ifdef ESP8266
+ || PWM_DIMMER == my_module_type
+#endif
+ )
{
char *brightness_command_topic = stemp1;
@@ -423,10 +427,13 @@ void HAssAnnounceButtons(void)
uint8_t toggle = 1;
uint8_t hold = 0;
+#ifdef ESP8266
if (!button_index && ((SONOFF_DUAL == my_module_type) || (CH4 == my_module_type)))
{
button_present = 1;
- } else {
+ } else
+#endif
+ {
if (pin[GPIO_KEY1 + button_index] < 99) {
button_present = 1;
}
@@ -481,8 +488,8 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const
char subname[20];
mqtt_data[0] = '\0'; // Clear retained message
-
- // Clear or Set topic
+
+ // Clear or Set topic
NoAlNumToUnderscore(subname, MultiSubName); //Replace all non alphaumeric characters to '_' to avoid topic name issues
snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%s"), ESP.getChipId(), sensorname, subname);
snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id);
@@ -517,7 +524,7 @@ void HAssAnnounceSensor(const char *sensorname, const char *subsensortype, const
case 3:
snprintf_P(param1, sizeof(param1), PSTR("%s"), PressureUnit().c_str());
break;
- // case 4: // Speed. Default to km/h if not set to have a graph representation under HAss
+ // case 4: // Speed. Default to km/h if not set to have a graph representation under HAss
// case 5:
// case 6:
// case 7:
@@ -596,8 +603,8 @@ void HAssAnnounceSensors(void)
for (auto subsensor : subsensors) {
snprintf_P(NewSensorName, sizeof(NewSensorName), PSTR("%s %s"), NestedName, subsensor.key);
HAssAnnounceSensor(sensorname, NestedName, NewSensorName, 0, 0, 1, subsensor.key);
- }
- } else if (subsensor.value.is()) {
+ }
+ } else if (subsensor.value.is()) {
// If there is more than a value on sensor data, 'n' entitites will be created
JsonArray& subsensors = subsensor.value.as();
uint8_t subqty = subsensors.size();
diff --git a/tasmota/xdrv_13_display.ino b/tasmota/xdrv_13_display.ino
index 117725024..e490d0bd1 100644
--- a/tasmota/xdrv_13_display.ino
+++ b/tasmota/xdrv_13_display.ino
@@ -838,7 +838,7 @@ void DisplayText(void)
if (!fill) {
*dp = 0;
} else {
- linebuf[abs(fill)] = 0;
+ linebuf[abs(int(fill))] = 0;
}
if (fill<0) {
// right align
diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino
index b68de3c8d..c91b8604d 100644
--- a/tasmota/xdrv_27_shutter.ino
+++ b/tasmota/xdrv_27_shutter.ino
@@ -37,16 +37,18 @@ enum ShutterModes { SHT_OFF_OPEN__OFF_CLOSE, SHT_OFF_ON__OPEN_CLOSE, SHT_PULSE_O
enum ShutterButtonStates { SHT_NOT_PRESSED, SHT_PRESSED_MULTI, SHT_PRESSED_HOLD, SHT_PRESSED_IMMEDIATE, SHT_PRESSED_EXT_HOLD, SHT_PRESSED_MULTI_SIMULTANEOUS, SHT_PRESSED_HOLD_SIMULTANEOUS, SHT_PRESSED_EXT_HOLD_SIMULTANEOUS,};
const char kShutterCommands[] PROGMEM = D_PRFX_SHUTTER "|"
- D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|"
+ D_CMND_SHUTTER_OPEN "|" D_CMND_SHUTTER_CLOSE "|" D_CMND_SHUTTER_TOGGLE "|" D_CMND_SHUTTER_STOP "|" D_CMND_SHUTTER_POSITION "|"
D_CMND_SHUTTER_OPENTIME "|" D_CMND_SHUTTER_CLOSETIME "|" D_CMND_SHUTTER_RELAY "|"
D_CMND_SHUTTER_SETHALFWAY "|" D_CMND_SHUTTER_SETCLOSE "|" D_CMND_SHUTTER_INVERT "|" D_CMND_SHUTTER_CLIBRATION "|"
- D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK "|" D_CMND_SHUTTER_ENABLEENDSTOPTIME "|" D_CMND_SHUTTER_INVERTWEBBUTTONS;
+ D_CMND_SHUTTER_MOTORDELAY "|" D_CMND_SHUTTER_FREQUENCY "|" D_CMND_SHUTTER_BUTTON "|" D_CMND_SHUTTER_LOCK "|" D_CMND_SHUTTER_ENABLEENDSTOPTIME "|" D_CMND_SHUTTER_INVERTWEBBUTTONS "|"
+ D_CMND_SHUTTER_STOPOPEN "|" D_CMND_SHUTTER_STOPCLOSE "|" D_CMND_SHUTTER_STOPTOGGLE "|" D_CMND_SHUTTER_STOPPOSITION;
void (* const ShutterCommand[])(void) PROGMEM = {
- &CmndShutterOpen, &CmndShutterClose, &CmndShutterStop, &CmndShutterPosition,
+ &CmndShutterOpen, &CmndShutterClose, &CmndShutterToggle, &CmndShutterStop, &CmndShutterPosition,
&CmndShutterOpenTime, &CmndShutterCloseTime, &CmndShutterRelay,
&CmndShutterSetHalfway, &CmndShutterSetClose, &CmndShutterInvert, &CmndShutterCalibration , &CmndShutterMotorDelay,
- &CmndShutterFrequency, &CmndShutterButton, &CmndShutterLock, &CmndShutterEnableEndStopTime, &CmndShutterInvertWebButtons};
+ &CmndShutterFrequency, &CmndShutterButton, &CmndShutterLock, &CmndShutterEnableEndStopTime, &CmndShutterInvertWebButtons,
+ &CmndShutterStopOpen, &CmndShutterStopClose, &CmndShutterStopToggle, &CmndShutterStopPosition};
const char JSON_SHUTTER_POS[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Position\":%d,\"Direction\":%d,\"Target\":%d}";
const char JSON_SHUTTER_BUTTON[] PROGMEM = "\"" D_PRFX_SHUTTER "%d\":{\"Button%d\":%d}";
@@ -677,7 +679,13 @@ void ShutterButtonHandler(void)
CmndShutterStop();
} else {
XdrvMailbox.payload = position = (position-1)<<1;
- CmndShutterPosition();
+ //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: shutter %d -> %d"), shutter_index+1, position);
+ if (102 == position) {
+ XdrvMailbox.payload = XdrvMailbox.index;
+ CmndShutterToggle();
+ } else {
+ CmndShutterPosition();
+ }
if (Settings.shutter_button[button_index] & ((0x01<<26)< 0) && (XdrvMailbox.index <= shutters_present)) {
+ uint32_t index = XdrvMailbox.index-1;
+ if (Shutter.direction[index]) {
+ CmndShutterStop();
+ } else {
+ CmndShutterOpen();
+ }
+ }
+}
+
void CmndShutterClose(void)
{
- //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload open: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.i);
+ //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload close: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index);
if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) {
XdrvMailbox.index = XdrvMailbox.payload;
}
@@ -739,6 +758,45 @@ void CmndShutterClose(void)
CmndShutterPosition();
}
+void CmndShutterStopClose(void)
+{
+ if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
+ uint32_t index = XdrvMailbox.index-1;
+ if (Shutter.direction[index]) {
+ CmndShutterStop();
+ } else {
+ CmndShutterClose();
+ }
+ }
+}
+
+void CmndShutterToggle(void)
+{
+ //AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Payload toggle: %d, i %d"), XdrvMailbox.payload, XdrvMailbox.index);
+ if ((1 == XdrvMailbox.index) && (XdrvMailbox.payload != -99)) {
+ XdrvMailbox.index = XdrvMailbox.payload;
+ }
+ if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
+ uint32_t index = XdrvMailbox.index-1;
+ XdrvMailbox.payload = (50 < ShutterRealToPercentPosition(Shutter.real_position[index], index)) ? 0 : 100;
+ XdrvMailbox.data_len = 0;
+ last_source = SRC_WEBGUI;
+ CmndShutterPosition();
+ }
+}
+
+void CmndShutterStopToggle(void)
+{
+ if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
+ uint32_t index = XdrvMailbox.index-1;
+ if (Shutter.direction[index]) {
+ CmndShutterStop();
+ } else {
+ CmndShutterToggle();
+ }
+ }
+}
+
void CmndShutterStop(void)
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
@@ -779,15 +837,15 @@ void CmndShutterPosition(void)
// special handling fo UP,DOWN,TOGGLE,STOP command comming with payload -99
if ((XdrvMailbox.data_len > 1) && (XdrvMailbox.payload <= 0)) {
//UpperCase(XdrvMailbox.data, XdrvMailbox.data);
- if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_UP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_OPEN) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEUP))) {
+ if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_UP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_OPEN) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPOPEN))) {
CmndShutterOpen();
return;
}
- if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_DOWN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_CLOSE) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEDOWN))) {
+ if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_DOWN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_CLOSE) || ((Shutter.direction[index]==0) && !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPCLOSE))) {
CmndShutterClose();
return;
}
- if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOP) || ((Shutter.direction[index]) && (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEUP) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLEDOWN)))) {
+ if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOP) || ((Shutter.direction[index]) && (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPOPEN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPCLOSE)))) {
XdrvMailbox.payload = -99;
CmndShutterStop();
return;
@@ -861,6 +919,18 @@ void CmndShutterPosition(void)
}
}
+void CmndShutterStopPosition(void)
+{
+ if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
+ uint32_t index = XdrvMailbox.index-1;
+ if (Shutter.direction[index]) {
+ XdrvMailbox.payload = -99;
+ CmndShutterStop();
+ } else {
+ CmndShutterPosition();
+ }
+ }
+}
void CmndShutterOpenTime(void)
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= shutters_present)) {
@@ -928,10 +998,10 @@ void CmndShutterButton(void)
// (setting>>28)&(0x01) : mqtt broadcast tripple press
// (setting>>27)&(0x01) : mqtt broadcast double press
// (setting>>26)&(0x01) : mqtt broadcast single press
- // (setting>>20)&(0x3f) : shutter_position hold; 0 disabled, 1..101 == 0..100%
- // (setting>>14)&(0x3f) : shutter_position tripple press 0 disabled, 1..101 == 0..100%
- // (setting>> 8)&(0x3f) : shutter_position double press 0 disabled, 1..101 == 0..100%
- // (setting>> 2)&(0x3f) : shutter_position single press 0 disabled, 1..101 == 0..100%
+ // (setting>>20)&(0x3f) : shutter_position hold; 0 disabled, 1..101 == 0..100%, 102 == toggle
+ // (setting>>14)&(0x3f) : shutter_position tripple press 0 disabled, 1..101 == 0..100%, 102 == toggle
+ // (setting>> 8)&(0x3f) : shutter_position double press 0 disabled, 1..101 == 0..100%, 102 == toggle
+ // (setting>> 2)&(0x3f) : shutter_position single press 0 disabled, 1..101 == 0..100%, 102 == toggle
// (setting>> 0)&(0x03) : shutter_index
if (XdrvMailbox.data_len > 0) {
uint32_t i = 0;
@@ -945,10 +1015,16 @@ void CmndShutterButton(void)
// Loop through the data string, splitting on ' ' seperators.
for (char *str = strtok_r(data_copy, " ", &str_ptr); str && i < (1+4+4+1); str = strtok_r(nullptr, " ", &str_ptr), i++) {
int field;
- if (str[0] == '-') {
- field = -1;
- } else {
- field = atoi(str);
+ switch (str[0]) {
+ case '-':
+ field = -1;
+ break;
+ case 't':
+ field = 102;
+ break;
+ default:
+ field = atoi(str);
+ break;
}
switch (i) {
case 0:
@@ -971,18 +1047,22 @@ void CmndShutterButton(void)
setting |= (((100>>1)+1)<<2) | (((0>>1)+1)<<8) | (((50>>1)+1)<<14);
isShortCommand = true;
break;
+ } else if (!strcmp_P(str, PSTR("toggle"))) {
+ setting |= (((102>>1)+1)<<2) | (((50>>1)+1)<<8);
+ isShortCommand = true;
+ break;
}
case 2:
if (isShortCommand) {
if ((field==1) && (setting & (0x3F<<(2+6*3))))
- // if short command up or down then also enable MQTT broadcast
+ // if short command up or down (hold press position set) then also enable MQTT broadcast
setting |= (0x3<<29);
done = true;
break;
}
case 3:
case 4:
- if ((field >= -1) && (field<=100))
+ if ((field >= -1) && (field<=102))
setting |= (((field>>1)+1)<<(i*6 + (2-6)));
break;
case 5:
@@ -1023,8 +1103,12 @@ void CmndShutterButton(void)
for (uint32_t j=0 ; j < 4 ; j++) {
int8_t pos = (((setting>> (2+6*j))&(0x3f))-1)<<1;
- if (pos>=0)
- setting_chr_ptr += snprintf_P(setting_chr_ptr, 5, PSTR(" %d"), pos);
+ if (0 <= pos)
+ if (102 == pos) {
+ setting_chr_ptr += sprintf_P(setting_chr_ptr, PSTR(" t"));
+ } else {
+ setting_chr_ptr += snprintf_P(setting_chr_ptr, 5, PSTR(" %d"), pos);
+ }
else
setting_chr_ptr += sprintf_P(setting_chr_ptr, PSTR(" -"));
}
diff --git a/tasmota/xdrv_38_ping.ino b/tasmota/xdrv_38_ping.ino
new file mode 100644
index 000000000..c783f3ee9
--- /dev/null
+++ b/tasmota/xdrv_38_ping.ino
@@ -0,0 +1,169 @@
+/*
+ xdrv_38_ping.ino - support for ICMP Ping
+
+ Copyright (C) 2020 Theo Arends and Stephan Hadinger
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef USE_PING
+
+#define XDRV_38 38
+
+#include
+#include
+
+const char kPingCommands[] PROGMEM = "|" // no prefix
+ D_CMND_PING
+ ;
+
+void (* const PingCommand[])(void) PROGMEM = {
+ &CmndPing,
+ };
+
+// inspired by https://github.com/dancol90/ESP8266Ping
+
+typedef struct Ping_t {
+ ping_option opt; // extend the ping_option structure with internal values
+ uint16_t total_count; // total count if packets sent
+ uint16_t timeout_count; // time-outs (no responses)
+ uint32_t min_time; // minimum time in ms for a successful response
+ uint32_t max_time; // maximum time in ms for a successful response
+ uint32_t sum_time; // cumulated time in ms for all successful responses (used to compute the average)
+ bool done; // indicates the ping campaign is finished
+} Ping_t;
+
+std::vector pings = {};
+
+extern "C" {
+ // callbacks for ping
+
+ // called after a ping response is received or time-out
+ void ICACHE_RAM_ATTR ping_recv_cb(Ping_t *ping, struct ping_resp *p_resp) {
+ // If successful
+ if (p_resp->ping_err >= 0) {
+ uint32_t resp_time = p_resp->resp_time;
+ ping->sum_time += resp_time;
+ if (resp_time < ping->min_time) { ping->min_time = resp_time; }
+ if (resp_time > ping->max_time) { ping->max_time = resp_time; }
+ }
+ }
+
+ // called after the ping campaign is finished
+ void ICACHE_RAM_ATTR ping_sent_cb(Ping_t *ping, struct ping_resp *p_resp) {
+ // copy counters to build the MQTT response
+ ping->total_count = p_resp->total_count;
+ ping->timeout_count = p_resp->timeout_count;
+ ping->done = true;
+ }
+}
+
+// Check if any ping requests is completed, and publish the results
+void PingResponsePoll(void) {
+ for (auto it = pings.begin(); it != pings.end(); it++) {
+ Ping_t *ping = *it;
+ if (ping->done) {
+ uint32_t success = ping->total_count - ping->timeout_count;
+ uint32_t ip = ping->opt.ip;
+
+ // Serial.printf(
+ // "DEBUG ping_sent_cb: ping reply\n"
+ // "\tsuccess_count = %d \n"
+ // "\ttimeout_count = %d \n"
+ // "\tmin_time = %d \n"
+ // "\tmax_time = %d \n"
+ // "\tavg_time = %d \n",
+ // success, ping->timeout_count,
+ // ping->min_time, ping->max_time,
+ // success ? ping->sum_time / success : 0
+ // );
+
+ Response_P(PSTR("{\"" D_JSON_PING "\":{\"%d.%d.%d.%d\":{"
+ "\"Reachable\":%s"
+ ",\"Success\":%d"
+ ",\"Timeout\":%d"
+ ",\"MinTime\":%d"
+ ",\"MaxTime\":%d"
+ ",\"AvgTime\":%d"
+ "}}}"),
+ ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24,
+ success ? "true" : "false",
+ success, ping->timeout_count,
+ ping->min_time, ping->max_time,
+ success ? ping->sum_time / success : 0
+ );
+ MqttPublishPrefixTopic_P(RESULT_OR_TELE, PSTR(D_JSON_PING));
+ XdrvRulesProcess();
+
+ pings.erase(it--); // remove from list
+ delete ping; // free memory allocated
+ }
+ }
+}
+
+void CmndPing(void) {
+ uint32_t count = XdrvMailbox.index;
+ IPAddress ip;
+
+ RemoveSpace(XdrvMailbox.data);
+ if (count > 60) { count = 60; }
+
+ if (WiFi.hostByName(XdrvMailbox.data, ip)) {
+ Ping_t *ping = new Ping_t();
+ memset(ping, 0, sizeof(Ping_t ));
+ ping->min_time = UINT32_MAX;
+
+ ping_option &opt = ping->opt;
+ opt.count = count;
+ opt.coarse_time = 1; // wait 1 second between messages
+ opt.ip = ip;
+
+ // callbacks
+ opt.recv_function = (ping_recv_function) ping_recv_cb; // at each response or time-out
+ opt.sent_function = (ping_sent_function) ping_sent_cb; // when all packets have been sent and reveived
+
+ if (ping_start(&opt)) {
+ pings.push_back(ping);
+ ResponseCmndDone();
+ } else {
+ ResponseCmndChar_P(PSTR("Unable to send Ping"));
+ delete ping;
+ }
+ } else {
+ ResponseCmndChar_P(PSTR("Unable to resolve IP address"));
+ }
+
+}
+
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xdrv38(uint8_t function)
+{
+ bool result = false;
+
+ switch (function) {
+ case FUNC_EVERY_250_MSECOND:
+ PingResponsePoll();
+ break;
+ case FUNC_COMMAND:
+ result = DecodeCommand(kPingCommands, PingCommand);
+ break;
+ }
+ return result;
+}
+
+#endif // USE_PING
diff --git a/tasmota/xdsp_11_sevenseg.ino b/tasmota/xdsp_11_sevenseg.ino
new file mode 100644
index 000000000..80056aa6e
--- /dev/null
+++ b/tasmota/xdsp_11_sevenseg.ino
@@ -0,0 +1,306 @@
+/*
+ xdsp_11_sevenseg.ino - Display seven segment support for Tasmota
+
+ Copyright (C) 2020 Theo Arends and Adafruit
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef USE_I2C
+#ifdef USE_DISPLAY
+#ifdef USE_DISPLAY_SEVENSEG
+
+#define XDSP_11 11
+#define XI2C_47 47 // See I2CDEVICES.md
+
+#include
+#include
+#include // Seven segment LED
+
+Adafruit_7segment sevenseg = Adafruit_7segment();
+
+uint8_t sevenseg_state = 0;
+
+/*********************************************************************************************/
+
+void SevensegWrite(void)
+{
+ sevenseg.writeDisplay();
+}
+
+void SevensegClear(void)
+{
+ sevenseg.clear();
+ SevensegWrite();
+}
+
+
+/*********************************************************************************************/
+
+void SevensegInitMode(void)
+{
+ sevenseg.setBrightness(Settings.display_dimmer);
+ sevenseg.blinkRate(0); // 0 - 3
+ SevensegClear();
+}
+
+void SevensegInit(uint8_t mode)
+{
+ switch(mode) {
+ case DISPLAY_INIT_MODE:
+ case DISPLAY_INIT_PARTIAL:
+ case DISPLAY_INIT_FULL:
+ SevensegInitMode();
+ break;
+ }
+}
+
+void SevensegInitDriver(void)
+{
+ if (!Settings.display_model) {
+ if (I2cSetDevice(SEVENSEG_ADDRESS1)) {
+ Settings.display_model = XDSP_11;
+ }
+ }
+
+ if (XDSP_11 == Settings.display_model) {
+ sevenseg_state = 1;
+ sevenseg.begin(SEVENSEG_ADDRESS1);
+
+ Settings.display_width = 4;
+ Settings.display_height = 1;
+
+ SevensegInitMode();
+ }
+}
+
+void SevensegOnOff(void)
+{
+ if (!disp_power) { SevensegClear(); }
+}
+
+void SevensegDrawStringAt(uint16_t x, uint16_t y, char *str, uint16_t color, uint8_t flag)
+{
+ uint16_t number = 0;
+ boolean hasnumber= false;
+ uint8_t dots= 0;
+ boolean t=false;
+ boolean T=false;
+ boolean d=false;
+ boolean hex=false;
+ boolean done=false;
+ boolean s=false;
+ for (int i=0; (str[i]!='\0') && (!done); i++) {
+ // [prefix(es) chars]digits
+ // Some combinations won't make sense.
+ // Reference: https://learn.adafruit.com/adafruit-led-backpack/1-2-inch-7-segment-backpack-arduino-wiring-and-setup
+ // Some sample valid combinations:
+ // 787 -> 787
+ // x47 -> 2F
+ // st:241 -> 04:01
+ // sT241 -> 4 01
+ switch (str[i]) {
+ case 'x': // print given dec value as hex
+ hex = true;
+ break;
+ case ':': // print colon
+ dots |= 0x02;
+ break;
+ case '^': // print top_left_dot
+ dots |= 0x08;
+ break;
+ case 'v': // print bottom_left_dot
+ dots |= 0x04;
+ break;
+ case '.': // print ampm
+ dots |= 0x10;
+ break;
+ case 'T': // print as time 12 format
+ t = true;
+ break;
+ case 't': // print as time 24 format
+ T = true;
+ break;
+ case 's': // duration in seconds
+ s = true;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ hasnumber= true;
+ number = atoi(str+i);
+ done = true;
+ break;
+ default: // unknown format, ignore
+ break;
+ }
+ }
+
+ if (s) {
+ // number is duration in seconds
+ hex = false;
+ int hour = number/60/60;
+ int minute = (number/60)%60;
+
+ if (hour) {
+ // HH:MM
+ number = hour*100 + minute;
+ } else {
+ // MM:SS
+ number = minute*100 + number%60;
+ }
+ }
+
+ if (hasnumber) {
+ if (hex) {
+ sevenseg.print(number, HEX);
+ } else {
+ sevenseg.print(number, DEC);
+ }
+ }
+
+ if (dots) {
+ sevenseg.writeDigitRaw(2, dots);
+ }
+
+ sevenseg.writeDisplay();
+}
+
+/*********************************************************************************************/
+
+#ifdef USE_DISPLAY_MODES1TO5
+void SevensegTime(boolean time_24)
+{
+
+ uint hours = RtcTime.hour;
+ uint minutes = RtcTime.minute;
+ uint second = RtcTime.second;
+ uint16_t displayValue = hours * 100 + minutes;
+ uint16_t dots = 0;
+
+ // Do 24 hour to 12 hour format conversion when required.
+ if (!time_24) {
+ // Handle when hours are past 12 by subtracting 12 hours (1200 value).
+ if (hours > 12) {
+ displayValue -= 1200;
+ }
+ // Handle hour 0 (midnight) being shown as 12.
+ else if (hours == 0) {
+ displayValue += 1200;
+ }
+ }
+
+
+ // Now print the time value to the display.
+ sevenseg.print(displayValue, DEC);
+
+ // Add zero padding when in 24 hour mode and it's midnight.
+ // In this case the print function above won't have leading 0's
+ // which can look confusing. Go in and explicitly add these zeros.
+ if (time_24) {
+ if (hours == 0) {
+ // Pad hour 0.
+ sevenseg.writeDigitNum(1, 0);
+ // Also pad when the 10's minute is 0 and should be padded.
+ if (minutes < 10) {
+ sevenseg.writeDigitNum(3, 0);
+ }
+ }
+ if (hours < 10) {
+ // Always have 4 digits time
+ sevenseg.writeDigitNum(0, 0);
+ }
+ } else {
+ // Identify and display AM/PM
+ if (hours >= 12) {
+ dots |= 0x10;
+ }
+ }
+
+ sevenseg.writeDigitRaw(2, dots |= ((second%2) << 1));
+ sevenseg.writeDisplay();
+}
+
+#endif // USE_DISPLAY_MODES1TO5
+
+void SevensegRefresh(void) // Every second
+{
+ if (disp_power) {
+ if (Settings.display_mode) { // Mode 0 is User text
+ switch (Settings.display_mode) {
+ case 1: // Time 12
+ SevensegTime(false);
+ break;
+ case 2: // Time 24
+ SevensegTime(true);
+ break;
+ case 4: // Mqtt
+ case 3: // Local
+ case 5: { // Mqtt
+ break;
+ }
+ }
+ }
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xdsp11(uint8_t function)
+{
+ if (!I2cEnabled(XI2C_47)) { return false; }
+
+ bool result = false;
+
+ if (FUNC_DISPLAY_INIT_DRIVER == function) {
+ SevensegInitDriver();
+ }
+ else if (XDSP_11 == Settings.display_model) {
+ switch (function) {
+ case FUNC_DISPLAY_MODEL:
+ result = true;
+ break;
+ case FUNC_DISPLAY_INIT:
+ SevensegInit(dsp_init);
+ break;
+ case FUNC_DISPLAY_CLEAR:
+ SevensegClear();
+ break;
+ case FUNC_DISPLAY_EVERY_SECOND:
+ SevensegRefresh();
+ break;
+ case FUNC_DISPLAY_ONOFF:
+ case FUNC_DISPLAY_POWER:
+ SevensegOnOff();
+ break;
+ case FUNC_DISPLAY_DRAW_STRING:
+ SevensegDrawStringAt(dsp_x, dsp_y, dsp_str, dsp_color, dsp_flag);
+ break;
+ }
+ }
+ return result;
+}
+
+#endif // USE_DISPLAY_SEVENSEG
+#endif // USE_DISPLAY
+#endif // USE_I2C
diff --git a/tasmota/xsns_27_apds9960.ino b/tasmota/xsns_27_apds9960.ino
index c426d535a..cdb390c73 100644
--- a/tasmota/xsns_27_apds9960.ino
+++ b/tasmota/xsns_27_apds9960.ino
@@ -39,18 +39,18 @@
#define XSNS_27 27
#define XI2C_21 21 // See I2CDEVICES.md
-#if defined(USE_SHT) || defined(USE_VEML6070) || defined(USE_TSL2561)
- #warning **** Turned off conflicting drivers SHT and VEML6070 ****
- #ifdef USE_SHT
- #undef USE_SHT // SHT-Driver blocks gesture sensor
- #endif
- #ifdef USE_VEML6070
- #undef USE_VEML6070 // address conflict on the I2C-bus
- #endif
- #ifdef USE_TSL2561
- #undef USE_TSL2561 // possible address conflict on the I2C-bus
- #endif
-#endif
+// #if defined(USE_SHT) || defined(USE_VEML6070) || defined(USE_TSL2561)
+// #warning **** Turned off conflicting drivers SHT and VEML6070 ****
+// #ifdef USE_SHT
+// #undef USE_SHT // SHT-Driver blocks gesture sensor
+// #endif
+// #ifdef USE_VEML6070
+// #undef USE_VEML6070 // address conflict on the I2C-bus
+// #endif
+// #ifdef USE_TSL2561
+// #undef USE_TSL2561 // possible address conflict on the I2C-bus
+// #endif
+// #endif
#define APDS9960_I2C_ADDR 0x39
diff --git a/tasmota/xsns_37_rfsensor.ino b/tasmota/xsns_37_rfsensor.ino
index d58e06b66..87ce5c9d7 100644
--- a/tasmota/xsns_37_rfsensor.ino
+++ b/tasmota/xsns_37_rfsensor.ino
@@ -665,7 +665,7 @@ bool Xsns37(uint8_t function)
RfSnsAnalyzeRawSignal();
}
}
- sleep = 0;
+ ssleep = 0;
break;
case FUNC_EVERY_SECOND:
RfSnsEverySecond();
diff --git a/tasmota/xsns_66_iAQ.ino b/tasmota/xsns_66_iAQ.ino
new file mode 100644
index 000000000..d115d0965
--- /dev/null
+++ b/tasmota/xsns_66_iAQ.ino
@@ -0,0 +1,137 @@
+/*
+ xsns_66_iAQ.ino - Support for iAQ-Core - Indoor Air Quality Sensor Module
+
+ Copyright (C) 2020 Christian Baars and Theo Arends
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef USE_I2C
+#ifdef USE_IAQ
+
+#define XSNS_66 66
+#define XI2C_46 46 // See I2CDEVICES.md
+
+#define I2_ADR_IAQ 0x5a // collides with MLX90614 and maybe others
+
+#define IAQ_STATUS_OK 0x00
+#define IAQ_STATUS_BUSY 0x01
+#define IAQ_STATUS_WARM 0x10
+#define IAQ_STATUS_ERR 0x80
+#define IAQ_STATUS_I2C_ERR 0xFF
+
+struct {
+ int32_t resistance;
+ uint16_t pred;
+ uint16_t Tvoc;
+ uint8_t status;
+ bool ready;
+} iAQ;
+
+void IAQ_Init(void)
+{
+ if (!I2cSetDevice(I2_ADR_IAQ)) { return; }
+ I2cSetActiveFound(I2_ADR_IAQ, "IAQ");
+ iAQ.ready = true;
+}
+
+void IAQ_Read(void)
+{
+ uint8_t buf[9];
+ buf[2] = IAQ_STATUS_I2C_ERR; // populate entry with error code
+ Wire.requestFrom((uint8_t)I2_ADR_IAQ,sizeof(buf));
+ for( uint32_t i=0; i<9; i++ ) {
+ buf[i]= Wire.read();
+ }
+ // AddLog_P2(LOG_LEVEL_DEBUG, "iAQ: buffer %x %x %x %x %x %x %x %x %x ", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]);
+ iAQ.pred = (buf[0]<<8) + buf[1];
+ iAQ.status = buf[2];
+ iAQ.resistance = ((uint32_t)buf[3]<<24) + ((uint32_t)buf[4]<<16) + ((uint32_t)buf[5]<<8) + (uint32_t)buf[6];
+ iAQ.Tvoc = (buf[7]<<8) + buf[8];
+}
+
+/*********************************************************************************************\
+ * Presentation
+\*********************************************************************************************/
+
+#ifdef USE_WEBSERVER
+const char HTTP_SNS_IAQ[] PROGMEM =
+ "{s}iAQ-Core " D_ECO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}" // {s} = , {m} = | , {e} = |
+ "{s}iAQ-Core " D_TVOC "{m}%d " D_UNIT_PARTS_PER_BILLION "{e}";
+
+const char HTTP_SNS_IAQ_ERROR[] PROGMEM =
+ "{s}iAQ-Core {m} %s {e}";
+#endif
+
+void IAQ_Show(uint8_t json)
+{
+ IAQ_Read();
+
+ if (json) {
+ if (iAQ.status!=IAQ_STATUS_OK){
+ AddLog_P2(LOG_LEVEL_INFO, PSTR("iAQ: " D_ERROR " %x" ),iAQ.status);
+ return;
+ }
+ else {
+ ResponseAppend_P(PSTR(",\"IAQ\":{\"" D_JSON_ECO2 "\":%u,\"" D_JSON_TVOC "\":%u,\"" D_JSON_RESISTANCE "\":%u}"), iAQ.pred, iAQ.Tvoc, iAQ.resistance);
+#ifdef USE_DOMOTICZ
+ if (0 == tele_period) DomoticzSensor(DZ_AIRQUALITY, iAQ.pred);
+#endif // USE_DOMOTICZ
+ }
+#ifdef USE_WEBSERVER
+ } else {
+ switch(iAQ.status){
+ case IAQ_STATUS_OK:
+ WSContentSend_PD(HTTP_SNS_IAQ, iAQ.pred, iAQ.Tvoc);
+ break;
+ case IAQ_STATUS_WARM:
+ WSContentSend_PD(HTTP_SNS_IAQ_ERROR, D_START);
+ break;
+ default:
+ WSContentSend_PD(HTTP_SNS_IAQ_ERROR, D_ERROR);
+ }
+#endif
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xsns66(byte function)
+{
+ if (!I2cEnabled(XI2C_46)) { return false; }
+
+ bool result = false;
+
+ if (FUNC_INIT == function) {
+ IAQ_Init();
+ }
+ else if (iAQ.ready) {
+ switch (function) {
+ case FUNC_JSON_APPEND:
+ IAQ_Show(1);
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ IAQ_Show(0);
+ break;
+#endif // USE_WEBSERVER
+ }
+ }
+ return result;
+}
+
+#endif // USE_IAQ
+#endif // USE_I2C
\ No newline at end of file
diff --git a/tasmota/xsns_67_as3935.ino b/tasmota/xsns_67_as3935.ino
new file mode 100644
index 000000000..aade21dec
--- /dev/null
+++ b/tasmota/xsns_67_as3935.ino
@@ -0,0 +1,828 @@
+/*
+ xsns_67_as3935.ino - AS3935 Franklin Lightning Sensor support for Tasmota
+
+ Copyright (C) 2020 Martin Wagner
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+#ifdef USE_I2C
+#ifdef USE_AS3935
+/*********************************************************************************************\
+ * AS3935 Lightning Sensor
+ *
+ * I2C Address: 0x03
+\*********************************************************************************************/
+
+#define XSNS_67 67
+#define XI2C_48 48 // See I2CDEVICES.md
+
+#define D_NAME_AS3935 "AS3935"
+#define AS3935_ADDR 0x03
+
+// Reg mask shift
+#define IRQ_TBL 0x03, 0x0F, 0
+#define ENERGY_RAW_1 0x04, 0xFF, 0
+#define ENERGY_RAW_2 0x05, 0xFF, 0
+#define ENERGY_RAW_3 0x06, 0x1F, 0
+#define LGHT_DIST 0x07, 0x3F, 0
+#define DISP_TRCO 0x08, 0x20, 5
+#define DISP_LCO 0x08, 0x80, 7
+#define TUNE_CAPS 0x08, 0x0F, 0
+#define AFE_GB 0x00, 0x3E, 0
+#define WDTH 0x01, 0x0F, 0
+#define NF_LEVEL 0x01, 0x70, 4
+#define SPIKE_REJECT 0x02, 0x0F, 0
+#define MIN_NUM_LIGH 0x02, 0x30, 4
+#define DISTURBER 0x03, 0x20, 5
+#define LCO_FDIV 0x03, 0xC0, 6
+
+#define INDOORS 0x24
+#define OUTDOORS 0x1C
+
+// Translation
+// http
+#define D_AS3935_GAIN "gain:"
+#define D_AS3935_ENERGY "energy:"
+#define D_AS3935_DISTANCE "distance:"
+#define D_AS3935_DISTURBER "disturber:"
+#define D_AS3935_VRMS "µVrms:"
+// http Message
+#define D_AS3935_APRX "aprx.:"
+#define D_AS3935_AWAY "away"
+#define D_AS3935_LIGHT "lightning"
+#define D_AS3935_OUT "lightning out of range"
+#define D_AS3935_NOT "distance not determined"
+#define D_AS3935_ABOVE "lightning overhead"
+#define D_AS3935_NOISE "noise detected"
+#define D_AS3935_DISTDET "disturber detected"
+#define D_AS3935_INTNOEV "Interrupt with no Event!"
+#define D_AS3935_NOMESS "listening..."
+// CMD Status
+#define D_AS3935_ON "On"
+#define D_AS3935_OFF "Off"
+#define D_AS3935_INDOORS "Indoors"
+#define D_AS3935_OUTDOORS "Outdoors"
+#define D_AS3935_CAL_FAIL "calibration failed"
+#define D_AS3935_CAL_OK "calibration set to:"
+
+// Global
+const char HTTP_SNS_UNIT_KILOMETER[] PROGMEM = D_UNIT_KILOMETER;
+// Http
+const char HTTP_SNS_AS3935_ENERGY[] PROGMEM = "{s}" D_NAME_AS3935 " " D_AS3935_ENERGY " {m}%d{e}";
+const char HTTP_SNS_AS3935_DISTANZ[] PROGMEM = "{s}" D_NAME_AS3935 " " D_AS3935_DISTANCE " {m}%u " D_UNIT_KILOMETER "{e}";
+const char HTTP_SNS_AS3935_VRMS[] PROGMEM = "{s}" D_NAME_AS3935 " " D_AS3935_VRMS "{m}%#4u (%d){e}";
+
+const char HTTP_SNS_AS3935_OUTDOORS[] PROGMEM = "{s}%s " D_AS3935_GAIN " {m}" D_AS3935_OUTDOORS " {e}";
+const char HTTP_SNS_AS3935_INDOORS[] PROGMEM = "{s}%s " D_AS3935_GAIN " {m}" D_AS3935_INDOORS " {e}";
+const char* const HTTP_SNS_AS3935_GAIN[] PROGMEM = {HTTP_SNS_AS3935_INDOORS, HTTP_SNS_AS3935_OUTDOORS};
+
+const char HTTP_SNS_AS3935_DIST_ON[] PROGMEM = "{s}%s " D_AS3935_DISTURBER " {m}" D_AS3935_ON " {e}";
+const char HTTP_SNS_AS3935_DIST_OFF[] PROGMEM = "{s}%s " D_AS3935_DISTURBER " {m}" D_AS3935_OFF " {e}";
+const char* const HTTP_SNS_AS3935_DISTURBER[] PROGMEM = {HTTP_SNS_AS3935_DIST_OFF, HTTP_SNS_AS3935_DIST_ON};
+// http Messages
+const char HTTP_SNS_AS3935_EMPTY[] PROGMEM = "{s}%s: " D_AS3935_NOMESS "{e}";
+const char HTTP_SNS_AS3935_OUT[] PROGMEM = "{s}%s: " D_AS3935_OUT "{e}";
+const char HTTP_SNS_AS3935_NOT[] PROGMEM = "{s}%s: " D_AS3935_NOT "{e}";
+const char HTTP_SNS_AS3935_ABOVE[] PROGMEM = "{s}%s: " D_AS3935_ABOVE "{e}";
+const char HTTP_SNS_AS3935_NOISE[] PROGMEM = "{s}%s: " D_AS3935_NOISE "{e}";
+const char HTTP_SNS_AS3935_DISTURB[] PROGMEM = "{s}%s: " D_AS3935_DISTDET "{e}";
+const char HTTP_SNS_AS3935_INTNOEV[] PROGMEM = "{s}%s: " D_AS3935_INTNOEV "{e}";
+const char HTTP_SNS_AS3935_MSG[] PROGMEM = "{s}%s: " D_AS3935_LIGHT " " D_AS3935_APRX " %d " D_UNIT_KILOMETER " " D_AS3935_AWAY "{e}";
+const char* const HTTP_SNS_AS3935_TABLE_1[] PROGMEM = { HTTP_SNS_AS3935_EMPTY, HTTP_SNS_AS3935_MSG, HTTP_SNS_AS3935_OUT, HTTP_SNS_AS3935_NOT, HTTP_SNS_AS3935_ABOVE, HTTP_SNS_AS3935_NOISE, HTTP_SNS_AS3935_DISTURB, HTTP_SNS_AS3935_INTNOEV };
+// Json
+const char JSON_SNS_AS3935_EVENTS[] PROGMEM = ",\"%s\":{\"" D_JSON_EVENT "\":%d,\"" D_JSON_DISTANCE "\":%d,\"" D_JSON_ENERGY "\":%u}";
+// Json Command
+const char* const S_JSON_AS3935_COMMAND_ONOFF[] PROGMEM = {"\"" D_AS3935_OFF "\"","\"" D_AS3935_ON"\""};
+const char* const S_JSON_AS3935_COMMAND_GAIN[] PROGMEM = {"\"" D_AS3935_INDOORS "\"", "\"" D_AS3935_OUTDOORS "\""};
+const char* const S_JSON_AS3935_COMMAND_CAL[] PROGMEM = {"" D_AS3935_CAL_FAIL "","" D_AS3935_CAL_OK ""};
+
+const char S_JSON_AS3935_COMMAND_STRING[] PROGMEM = "{\"" D_NAME_AS3935 "\":{\"%s\":%s}}";
+const char S_JSON_AS3935_COMMAND_NVALUE[] PROGMEM = "{\"" D_NAME_AS3935 "\":{\"%s\":%d}}";
+const char S_JSON_AS3935_COMMAND_SETTINGS[] PROGMEM = "{\"" D_NAME_AS3935 "\":{\"Gain\":%s,\"NFfloor\":%d,\"uVrms\":%d,\"Tunecaps\":%d,\"MinNumLight\":%d,\"Rejektion\":%d,\"Wdthreshold\":%d,\"MinNFstage\":%d,\"NFAutoTime\":%d,\"DisturberAutoTime\":%d,\"Disturber\":%s,\"NFauto\":%s,\"Disturberauto\":%s,\"NFautomax\":%s,\"Mqttlightevent\":%s}}";
+
+const char kAS3935_Commands[] PROGMEM = "setnf|setminstage|setml|default|setgain|settunecaps|setrej|setwdth|disttime|nftime|disturber|autonf|autodisturber|autonfmax|mqttevent|settings|calibrate";
+
+enum AS3935_Commands { // commands for Console
+ CMND_AS3935_SET_NF, // Noise Floor Level, value from 0-7 (3 Bit)
+ CMND_AS3935_SET_MINNF, // Set Min Noise Floor Level when Autotune is active Value von 0-15
+ CMND_AS3935_SET_MINLIGHT, // Minimum number of lightning 0=1/1=5/2=9/3=16 Lightnings
+ CMND_AS3935_SET_DEF, // set default for Sensor and Settings
+ CMND_AS3935_SET_GAIN, // Set Inddoor/Outdoor
+ CMND_AS3935_SET_TUNE, // Internal Tuning Capacitors (from 0 to 120pF in steps of 8pf)
+ CMND_AS3935_SET_REJ, // Set Spike Rejection
+ CMND_AS3935_SET_WDTH, // Watchdog threshold
+ CMND_AS3935_DISTTIME, // Threshhold Time for Auto Disturber
+ CMND_AS3935_NFTIME, // Threshhold Time for NF-Autotune
+ CMND_AS3935_SET_DISTURBER, // Set Disturber on/off
+ CMND_AS3935_NF_AUTOTUNE, // Autotune the NF Noise
+ CMND_AS3935_DIST_AUTOTUNE, // Autotune Disturber on/off
+ CMND_AS3935_NF_ATUNE_BOTH, // Autotune over both Areas: INDOORS/OUDOORS
+ CMND_AS3935_MQTT_LIGHT_EVT, // mqtt only if lightning Irq
+ CMND_AS3935_SETTINGS, // Json output of all settings
+ CMND_AS3935_CALIBRATE // caps autocalibrate
+ };
+
+struct AS3935STRUCT
+{
+ bool autodist_activ = false;
+ volatile bool detected = false;
+ volatile bool dispLCO = 0;
+ uint8_t icount = 0;
+ uint8_t irq = 0;
+ uint8_t mqtt_irq = 0;
+ uint8_t http_irq = 0;
+ uint8_t http_count_start = 0;
+ int16_t http_distance = 0;
+ int16_t distance = 0;
+ uint16_t http_timer = 0;
+ uint16_t http_count = 0;
+ uint16_t nftimer = 0;
+ uint16_t disttimer = 0;
+ uint32_t intensity = 0;
+ uint32_t http_intensity = 0;
+ volatile uint32_t pulse = 0;
+} as3935_sensor;
+
+uint8_t as3935_active = 0;
+
+void ICACHE_RAM_ATTR AS3935Isr() {
+ as3935_sensor.detected = true;
+}
+
+uint8_t AS3935ReadRegister(uint8_t reg, uint8_t mask, uint8_t shift) {
+ uint8_t data = I2cRead8(AS3935_ADDR, reg);
+ if (reg == 0x08) Settings.as3935_sensor_cfg[4] = data;
+ if (reg < 0x04) Settings.as3935_sensor_cfg[reg] = data;
+ return ((data & mask) >> shift);
+}
+
+void AS3935WriteRegister(uint8_t reg, uint8_t mask, uint8_t shift, uint8_t data) {
+ uint8_t currentReg = I2cRead8(AS3935_ADDR, reg);
+ currentReg &= (~mask);
+ data <<= shift;
+ data &= mask;
+ data |= currentReg;
+ I2cWrite8(AS3935_ADDR, reg, data);
+ if (reg == 0x08) Settings.as3935_sensor_cfg[4] = I2cRead8(AS3935_ADDR, reg);
+ if (reg < 0x04) Settings.as3935_sensor_cfg[reg] = I2cRead8(AS3935_ADDR, reg);
+}
+
+/********************************************************************************************/
+// Autotune Caps
+void ICACHE_RAM_ATTR AS3935CountFreq() {
+ if (as3935_sensor.dispLCO)
+ as3935_sensor.pulse++;
+}
+
+bool AS3935AutoTuneCaps(uint8_t irqpin) {
+ int32_t maxtune = 17500; // there max 3.5 % tol
+ uint8_t besttune;
+ AS3935WriteRegister(LCO_FDIV, 0); // Fdiv 16
+ delay(2);
+ for (uint8_t tune = 0; tune < 16; tune++) {
+ AS3935WriteRegister(TUNE_CAPS, tune);
+ delay(2);
+ AS3935WriteRegister(DISP_LCO,1);
+ delay(1);
+ as3935_sensor.dispLCO = true;
+ as3935_sensor.pulse = 0;
+ attachInterrupt(digitalPinToInterrupt(irqpin), AS3935CountFreq, RISING);
+ delay(200); // 100ms callback not work accurat for fequ. measure
+ as3935_sensor.dispLCO = false;
+ detachInterrupt(irqpin);
+ AS3935WriteRegister(DISP_LCO,0);
+ int32_t currentfreq = 500000 - ((as3935_sensor.pulse * 5) * 16);
+ if(currentfreq < 0) currentfreq = -currentfreq;
+ if(maxtune > currentfreq) {
+ maxtune = currentfreq;
+ besttune = tune;
+ }
+ }
+ if (maxtune >= 17500) // max. 3.5%
+ return false;
+ AS3935SetTuneCaps(besttune);
+ return true;
+}
+
+/********************************************************************************************/
+// functions
+void AS3935CalibrateRCO() {
+ I2cWrite8(AS3935_ADDR, 0x3D, 0x96);
+ AS3935WriteRegister(DISP_TRCO, 1);
+ delay(2);
+ AS3935WriteRegister(DISP_TRCO, 0);
+}
+
+uint8_t AS3935TransMinLights(uint8_t min_lights) {
+ if (5 > min_lights) {
+ return 0;
+ } else if (9 > min_lights) {
+ return 1;
+ } else if (16 > min_lights) {
+ return 2;
+ } else {
+ return 3;
+ }
+}
+
+uint8_t AS3935TranslMinLightsInt(uint8_t min_lights) {
+ switch (min_lights) {
+ case 0: return 1;
+ case 1: return 5;
+ case 2: return 9;
+ case 3: return 16;
+ }
+}
+
+uint8_t AS3935TranslIrq(uint8_t irq, uint8_t distance) {
+ switch(irq) {
+ case 0: return 7; // Interrupt with no IRQ
+ case 1: return 5; // Noise level too high
+ case 4: return 6; // Disturber detected
+ case 8:
+ if (distance == -1) return 2; // Lightning out of Distance
+ else if (distance == 0) return 3; // Distance cannot be determined
+ else if (distance == 1) return 4; // Storm is Overhead
+ else return 1; // Lightning with Distance detected
+ }
+}
+
+void AS3935CalcVrmsLevel(uint16_t &vrms, uint8_t &stage)
+{
+ uint8_t room = AS3935GetGain();
+ uint8_t nflev = AS3935GetNoiseFloor();
+ if (room == 0x24)
+ {
+ switch (nflev){
+ case 0x00:
+ vrms = 28;
+ break;
+ case 0x01:
+ vrms = 45;
+ break;
+ case 0x02:
+ vrms = 62;
+ break;
+ case 0x03:
+ vrms = 78;
+ break;
+ case 0x04:
+ vrms = 95;
+ break;
+ case 0x05:
+ vrms = 112;
+ break;
+ case 0x06:
+ vrms = 130;
+ break;
+ case 0x07:
+ vrms = 146;
+ break;
+ }
+ stage = nflev;
+ }
+ else
+ {
+ switch (nflev)
+ {
+ case 0x00:
+ vrms = 390;
+ break;
+ case 0x01:
+ vrms = 630;
+ break;
+ case 0x02:
+ vrms = 860;
+ break;
+ case 0x03:
+ vrms = 1100;
+ break;
+ case 0x04:
+ vrms = 1140;
+ break;
+ case 0x05:
+ vrms = 1570;
+ break;
+ case 0x06:
+ vrms = 1800;
+ break;
+ case 0x07:
+ vrms = 2000;
+ break;
+ }
+ stage = nflev + 8;
+ }
+}
+
+/********************************************************************************************/
+uint8_t AS3935GetIRQ() {
+ delay(2);
+ return AS3935ReadRegister(IRQ_TBL);
+}
+
+uint8_t AS3935GetDistance() {
+ return AS3935ReadRegister(LGHT_DIST);
+}
+
+int16_t AS3935CalcDistance() {
+ uint8_t dist = AS3935GetDistance();
+ switch (dist) {
+ case 0x3F: return -1; // Out of Range
+ case 0x01: return 1; // Storm is Overhead
+ case 0x00: return 0; // Distance cannot be determined
+ default:
+ if (40 < dist){
+ return 40;// limited because higher is not accurate
+ }
+ return dist;
+ }
+}
+
+uint32_t AS3935GetIntensity() {
+ uint32_t nrgy_raw = (AS3935ReadRegister(ENERGY_RAW_3) << 8);
+ nrgy_raw |= AS3935ReadRegister(ENERGY_RAW_2);
+ nrgy_raw <<= 8;
+ nrgy_raw |= AS3935ReadRegister(ENERGY_RAW_1);
+ return nrgy_raw;
+}
+
+uint8_t AS3935GetTuneCaps() {
+ return AS3935ReadRegister(TUNE_CAPS);
+}
+
+void AS3935SetTuneCaps(uint8_t tune) {
+ AS3935WriteRegister(TUNE_CAPS, tune);
+ delay(2);
+ AS3935CalibrateRCO();
+}
+
+uint8_t AS3935GetDisturber() {
+ return AS3935ReadRegister(DISTURBER);
+}
+
+uint8_t AS3935SetDisturber(uint8_t stat) {
+ AS3935WriteRegister(DISTURBER, stat);
+}
+
+uint8_t AS3935GetMinLights() {
+ return AS3935ReadRegister(MIN_NUM_LIGH);
+}
+
+uint8_t AS3935SetMinLights(uint8_t stat) {
+ AS3935WriteRegister(MIN_NUM_LIGH, stat);
+}
+
+uint8_t AS3935GetNoiseFloor() {
+ return AS3935ReadRegister(NF_LEVEL);
+}
+
+uint8_t AS3935SetNoiseFloor(uint8_t noise) {
+ AS3935WriteRegister(NF_LEVEL , noise);
+}
+
+uint8_t AS3935GetGain() {
+ if (AS3935ReadRegister(AFE_GB) == OUTDOORS)
+ return OUTDOORS;
+ return INDOORS;
+}
+
+uint8_t AS3935SetGain(uint8_t room) {
+ AS3935WriteRegister(AFE_GB, room);
+}
+
+uint8_t AS3935GetGainInt() {
+ if (AS3935ReadRegister(AFE_GB) == OUTDOORS)
+ return 1;
+return 0;
+}
+
+uint8_t AS3935GetSpikeRejection() {
+ return AS3935ReadRegister(SPIKE_REJECT);
+}
+
+void AS3935SetSpikeRejection(uint8_t rej) {
+ AS3935WriteRegister(SPIKE_REJECT, rej);
+}
+
+uint8_t AS3935GetWdth() {
+ return AS3935ReadRegister(WDTH);
+}
+
+void AS3935SetWdth(uint8_t wdth) {
+ AS3935WriteRegister(WDTH, wdth);
+}
+
+bool AS3935AutoTune(){
+ detachInterrupt(pin[GPIO_AS3935]);
+ bool result = AS3935AutoTuneCaps(pin[GPIO_AS3935]);
+ attachInterrupt(digitalPinToInterrupt(pin[GPIO_AS3935]), AS3935Isr, RISING);
+ return result;
+}
+
+/********************************************************************************************/
+// Noise Floor autofunctions
+bool AS3935LowerNoiseFloor() {
+ uint8_t noise = AS3935GetNoiseFloor();
+ uint16_t vrms;
+ uint8_t stage;
+ AS3935CalcVrmsLevel(vrms, stage);
+ if (Settings.as3935_functions.nf_autotune_both) {
+ if (stage == 8 && stage > Settings.as3935_parameter.nf_autotune_min) {
+ AS3935SetGain(INDOORS);
+ AS3935SetNoiseFloor(7);
+ return true;
+ }
+ }
+ if (0 < noise && stage > Settings.as3935_parameter.nf_autotune_min) {
+ noise--;
+ AS3935SetNoiseFloor(noise);
+ return true;
+ }
+ return false;
+}
+
+bool AS3935RaiseNoiseFloor() {
+ uint8_t noise = AS3935GetNoiseFloor();
+ uint8_t room = AS3935GetGain();
+ if (Settings.as3935_functions.nf_autotune_both) {
+ if (7 == noise && room == INDOORS) {
+ AS3935SetGain(OUTDOORS);
+ AS3935SetNoiseFloor(0);
+ return true;
+ }
+ }
+ if (7 > noise) {
+ noise++;
+ AS3935SetNoiseFloor(noise);
+ return true;
+ }
+ return false;
+}
+
+/********************************************************************************************/
+// init functions
+bool AS3935SetDefault() {
+ I2cWrite8(AS3935_ADDR, 0x3C, 0x96); // Set default
+ delay(2);
+ Settings.as3935_sensor_cfg[0] = I2cRead8(AS3935_ADDR, 0x00);
+ Settings.as3935_sensor_cfg[1] = I2cRead8(AS3935_ADDR, 0x01);
+ Settings.as3935_sensor_cfg[2] = I2cRead8(AS3935_ADDR, 0x02);
+ Settings.as3935_sensor_cfg[3] = I2cRead8(AS3935_ADDR, 0x03);
+ Settings.as3935_sensor_cfg[4] = I2cRead8(AS3935_ADDR, 0x08);
+ Settings.as3935_parameter.nf_autotune_min = 0x00;
+ Settings.as3935_parameter.nf_autotune_time = 4;
+ Settings.as3935_parameter.dist_autotune_time = 1;
+ return true;
+}
+
+void AS3935InitSettings() {
+ if(Settings.as3935_functions.nf_autotune){
+ AS3935SetGain(INDOORS);
+ AS3935SetNoiseFloor(0);
+ }
+ I2cWrite8(AS3935_ADDR, 0x00, Settings.as3935_sensor_cfg[0]);
+ I2cWrite8(AS3935_ADDR, 0x01, Settings.as3935_sensor_cfg[1]);
+ I2cWrite8(AS3935_ADDR, 0x02, Settings.as3935_sensor_cfg[2]);
+ I2cWrite8(AS3935_ADDR, 0x03, Settings.as3935_sensor_cfg[3]);
+ I2cWrite8(AS3935_ADDR, 0x08, Settings.as3935_sensor_cfg[4]);
+ delay(2);
+}
+
+void AS3935Setup(void) {
+ if (Settings.as3935_sensor_cfg[0] == 0x00) {
+ AS3935SetDefault();
+ } else {
+ AS3935InitSettings();
+ }
+ AS3935CalibrateRCO();
+}
+
+bool AS3935init() {
+ uint8_t ret = I2cRead8(AS3935_ADDR, 0x00);
+ if(INDOORS == ret || OUTDOORS == ret) // 0x24
+ return true;
+ return false;
+}
+
+void AS3935Detect(void) {
+ if (I2cActive(AS3935_ADDR)) return;
+ if (AS3935init())
+ {
+ I2cSetActiveFound(AS3935_ADDR, D_NAME_AS3935);
+ pinMode(pin[GPIO_AS3935], INPUT);
+ attachInterrupt(digitalPinToInterrupt(pin[GPIO_AS3935]), AS3935Isr, RISING);
+ AS3935Setup();
+ as3935_active = 1;
+ }
+}
+
+void AS3935EverySecond() {
+ if (as3935_sensor.detected) {
+ as3935_sensor.irq = AS3935GetIRQ(); // 1 =Noise, 4 = Disturber, 8 = storm
+ switch (as3935_sensor.irq) {
+ case 1:
+ if (Settings.as3935_functions.nf_autotune) {
+ if (AS3935RaiseNoiseFloor()) as3935_sensor.nftimer = 0;
+ }
+ break;
+ case 4:
+ if (Settings.as3935_functions.dist_autotune) {
+ AS3935SetDisturber(1);
+ as3935_sensor.autodist_activ = true;
+ }
+ break;
+ case 8:
+ as3935_sensor.intensity = AS3935GetIntensity();
+ as3935_sensor.distance = AS3935CalcDistance();
+ as3935_sensor.http_intensity = as3935_sensor.intensity;
+ as3935_sensor.http_distance = as3935_sensor.distance;
+ break;
+ }
+ // http show
+ as3935_sensor.http_irq = AS3935TranslIrq(as3935_sensor.irq, as3935_sensor.distance);
+ // mqtt publish
+ as3935_sensor.mqtt_irq = as3935_sensor.http_irq;
+ switch (as3935_sensor.mqtt_irq) {
+ case 5:
+ case 6:
+ if (!Settings.as3935_functions.mqtt_only_Light_Event) {
+ MqttPublishSensor();
+ as3935_sensor.http_timer = 10;
+ }
+ break;
+ default:
+ as3935_sensor.http_timer = 60;
+ MqttPublishSensor();
+ }
+ // clear mqtt events for Teleperiod
+ as3935_sensor.intensity = 0;
+ as3935_sensor.distance = 0;
+ as3935_sensor.mqtt_irq = 0;
+ // start http times
+ as3935_sensor.http_count_start = 1;
+ as3935_sensor.icount++; // Int counter
+ as3935_sensor.detected = false;
+ }
+
+ if (as3935_sensor.http_count_start) as3935_sensor.http_count++;
+ // clear Http
+ if (as3935_sensor.http_count == as3935_sensor.http_timer) {
+ as3935_sensor.http_count = 0;
+ as3935_sensor.http_count_start = 0;
+ as3935_sensor.http_intensity = 0;
+ as3935_sensor.http_distance = 0;
+ as3935_sensor.http_irq = 0;
+ }
+ // Noise Floor Autotune function
+ if (Settings.as3935_functions.nf_autotune) {
+ as3935_sensor.nftimer++;
+ if (as3935_sensor.nftimer > Settings.as3935_parameter.nf_autotune_time * 60) {
+ AS3935LowerNoiseFloor();
+ as3935_sensor.nftimer = 0;
+ }
+ }
+ // Disturber auto function
+ if (Settings.as3935_functions.dist_autotune) {
+ if (as3935_sensor.autodist_activ) as3935_sensor.disttimer++;
+ if (as3935_sensor.disttimer >= Settings.as3935_parameter.dist_autotune_time * 60) {
+ AS3935SetDisturber(0);
+ as3935_sensor.disttimer = 0;
+ as3935_sensor.autodist_activ = false;
+ }
+ }
+}
+
+bool AS3935Cmd(void) {
+ char command[CMDSZ];
+ uint8_t name_len = strlen(D_NAME_AS3935);
+ if (!strncasecmp_P(XdrvMailbox.topic, PSTR(D_NAME_AS3935), name_len)) {
+ uint32_t command_code = GetCommandCode(command, sizeof(command), XdrvMailbox.topic + name_len, kAS3935_Commands);
+ switch (command_code) {
+ case CMND_AS3935_SET_NF:
+ if (XdrvMailbox.data_len) {
+ if (15 >= XdrvMailbox.payload) {
+ AS3935SetNoiseFloor(XdrvMailbox.payload);
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935GetNoiseFloor());
+ break;
+ case CMND_AS3935_SET_MINNF:
+ if (XdrvMailbox.data_len) {
+ if (15 >= XdrvMailbox.payload) {
+ Settings.as3935_parameter.nf_autotune_min = XdrvMailbox.payload;
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, Settings.as3935_parameter.nf_autotune_min);
+ break;
+ case CMND_AS3935_SET_MINLIGHT:
+ if (XdrvMailbox.data_len) {
+ AS3935SetMinLights(AS3935TransMinLights(XdrvMailbox.payload));
+ }
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935TranslMinLightsInt(AS3935GetMinLights()));
+ break;
+ case CMND_AS3935_SET_DEF:
+ if (!XdrvMailbox.data_len) {
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935SetDefault());
+ }
+ break;
+ case CMND_AS3935_SET_GAIN:
+ if (XdrvMailbox.data_len > 6) {
+ uint8_t data_len = strlen(D_AS3935_OUTDOORS);
+ if (!strncasecmp_P(XdrvMailbox.data, PSTR(D_AS3935_OUTDOORS), data_len)) {
+ AS3935SetGain(OUTDOORS);
+ } else {
+ AS3935SetGain(INDOORS);
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_GAIN[AS3935GetGainInt()]);
+ break;
+ case CMND_AS3935_SET_TUNE:
+ if (XdrvMailbox.data_len) {
+ if (15 >= XdrvMailbox.payload) {
+ AS3935SetTuneCaps(XdrvMailbox.payload);
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935GetTuneCaps());
+ break;
+ case CMND_AS3935_SET_REJ:
+ if (XdrvMailbox.data_len) {
+ if (15 >= XdrvMailbox.payload) {
+ AS3935SetSpikeRejection(XdrvMailbox.payload);
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935GetSpikeRejection());
+ break;
+ case CMND_AS3935_SET_WDTH:
+ if (XdrvMailbox.data_len) {
+ if (15 >= XdrvMailbox.payload) {
+ AS3935SetWdth(XdrvMailbox.payload);
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, AS3935GetWdth());
+ break;
+ case CMND_AS3935_DISTTIME:
+ if (XdrvMailbox.data_len) {
+ if (15 >= XdrvMailbox.payload) {
+ Settings.as3935_parameter.dist_autotune_time = XdrvMailbox.payload;
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, Settings.as3935_parameter.dist_autotune_time);
+ break;
+ case CMND_AS3935_NFTIME:
+ if (XdrvMailbox.data_len) {
+ if (15 >= XdrvMailbox.payload) {
+ Settings.as3935_parameter.nf_autotune_time = XdrvMailbox.payload;
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, command, Settings.as3935_parameter.nf_autotune_time);
+ break;
+ case CMND_AS3935_SET_DISTURBER:
+ if (XdrvMailbox.data_len) {
+ if (2 > XdrvMailbox.payload) {
+ AS3935SetDisturber(XdrvMailbox.payload);
+ if (!XdrvMailbox.payload) Settings.as3935_functions.dist_autotune = 0;
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[AS3935GetDisturber()]);
+ break;
+ case CMND_AS3935_NF_AUTOTUNE:
+ if (XdrvMailbox.data_len) {
+ if (2 > XdrvMailbox.payload) {
+ Settings.as3935_functions.nf_autotune = XdrvMailbox.payload;
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[Settings.as3935_functions.nf_autotune]);
+ break;
+ case CMND_AS3935_DIST_AUTOTUNE:
+ if (XdrvMailbox.data_len) {
+ if (2 > XdrvMailbox.payload) {
+ Settings.as3935_functions.dist_autotune = XdrvMailbox.payload;
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[Settings.as3935_functions.dist_autotune]);
+ break;
+ case CMND_AS3935_NF_ATUNE_BOTH:
+ if (XdrvMailbox.data_len) {
+ if (2 > XdrvMailbox.payload) {
+ Settings.as3935_functions.nf_autotune_both = XdrvMailbox.payload;
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[Settings.as3935_functions.nf_autotune_both]);
+ break;
+ case CMND_AS3935_MQTT_LIGHT_EVT:
+ if (XdrvMailbox.data_len) {
+ if (2 > XdrvMailbox.payload) {
+ Settings.as3935_functions.mqtt_only_Light_Event = XdrvMailbox.payload;
+ }
+ }
+ Response_P(S_JSON_AS3935_COMMAND_STRING, command, S_JSON_AS3935_COMMAND_ONOFF[Settings.as3935_functions.mqtt_only_Light_Event]);
+ break;
+ case CMND_AS3935_SETTINGS: {
+ if (!XdrvMailbox.data_len) {
+ uint8_t gain = AS3935GetGainInt();
+ uint16_t vrms;
+ uint8_t stage;
+ AS3935CalcVrmsLevel(vrms, stage);
+ uint8_t nf_floor = AS3935GetNoiseFloor();
+ uint8_t min_nf = Settings.as3935_parameter.nf_autotune_min;
+ uint8_t tunecaps = AS3935GetTuneCaps();
+ uint8_t minnumlight = AS3935TranslMinLightsInt(AS3935GetMinLights());
+ uint8_t disturber = AS3935GetDisturber();
+ uint8_t reinj = AS3935GetSpikeRejection();
+ uint8_t wdth = AS3935GetWdth();
+ uint8_t nfauto = Settings.as3935_functions.nf_autotune;
+ uint8_t distauto = Settings.as3935_functions.dist_autotune;
+ uint8_t nfautomax = Settings.as3935_functions.nf_autotune_both;
+ uint8_t jsonlight = Settings.as3935_functions.mqtt_only_Light_Event;
+ uint8_t nf_time = Settings.as3935_parameter.nf_autotune_time;
+ uint8_t dist_time =Settings.as3935_parameter.dist_autotune_time;
+ Response_P(S_JSON_AS3935_COMMAND_SETTINGS, S_JSON_AS3935_COMMAND_GAIN[gain], nf_floor, vrms, tunecaps, minnumlight, reinj, wdth, min_nf, nf_time, dist_time, S_JSON_AS3935_COMMAND_ONOFF[disturber], S_JSON_AS3935_COMMAND_ONOFF[nfauto], S_JSON_AS3935_COMMAND_ONOFF[distauto], S_JSON_AS3935_COMMAND_ONOFF[nfautomax], S_JSON_AS3935_COMMAND_ONOFF[jsonlight]);
+ }
+ }
+ break;
+ case CMND_AS3935_CALIBRATE: {
+ bool calreslt;
+ if (!XdrvMailbox.data_len) calreslt = AS3935AutoTune();
+ Response_P(S_JSON_AS3935_COMMAND_NVALUE, S_JSON_AS3935_COMMAND_CAL[calreslt], AS3935GetTuneCaps());
+ }
+ break;
+ default:
+ return false;
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void AH3935Show(bool json)
+{
+ if (json) {
+ ResponseAppend_P(JSON_SNS_AS3935_EVENTS, D_SENSOR_AS3935, as3935_sensor.mqtt_irq, as3935_sensor.distance, as3935_sensor.intensity );
+
+#ifdef USE_WEBSERVER
+ } else {
+ uint8_t gain = AS3935GetGainInt();
+ uint8_t disturber = AS3935GetDisturber();
+ uint16_t vrms;
+ uint8_t stage;
+ AS3935CalcVrmsLevel(vrms, stage);
+
+ WSContentSend_PD(HTTP_SNS_AS3935_TABLE_1[as3935_sensor.http_irq], D_NAME_AS3935, as3935_sensor.http_distance);
+ WSContentSend_PD(HTTP_SNS_AS3935_DISTANZ, as3935_sensor.http_distance);
+ WSContentSend_PD(HTTP_SNS_AS3935_ENERGY, as3935_sensor.http_intensity);
+ WSContentSend_PD(HTTP_SNS_AS3935_GAIN[gain], D_NAME_AS3935);
+ WSContentSend_PD(HTTP_SNS_AS3935_DISTURBER[disturber], D_NAME_AS3935);
+ WSContentSend_PD(HTTP_SNS_AS3935_VRMS, vrms, stage);
+#endif // USE_WEBSERVER
+ }
+}
+
+/*********************************************************************************************\
+ * Interface
+\*********************************************************************************************/
+
+bool Xsns67(uint8_t function)
+{
+ if (!I2cEnabled(XI2C_48)) { return false; }
+
+ bool result = false;
+
+ if (FUNC_INIT == function) {
+ AS3935Detect();
+ }
+ else if (as3935_active) {
+ switch (function) {
+ case FUNC_EVERY_SECOND:
+ AS3935EverySecond();
+ break;
+ case FUNC_COMMAND:
+ result = AS3935Cmd();
+ break;
+ case FUNC_JSON_APPEND:
+ AH3935Show(1);
+ break;
+#ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ AH3935Show(0);
+ break;
+#endif // USE_WEBSERVER
+ }
+ }
+ return result;
+}
+
+#endif // USE_AS3935
+#endif // USE_I2C
diff --git a/tools/decode-status.py b/tools/decode-status.py
index 25af64a97..2450d1fb5 100755
--- a/tools/decode-status.py
+++ b/tools/decode-status.py
@@ -93,7 +93,7 @@ a_setoption = [[
"IR Unknown threshold",
"CSE7766 invalid power margin",
"Ignore hold time (s)",
- "(not used) Number of Tuya MCU relays",
+ "Gratuitous ARP repeat time",
"Over temperature threshold (celsius)",
"(not used) Tuya MCU max dimmer value",
"(not used) Tuya MCU voltage Id",
@@ -144,7 +144,9 @@ a_setoption = [[
"PWM Dimmer Turn red LED on when powered off",
"PWM Dimmer Buttons control remote devices",
"Distinct MQTT topics per device for Zigbee",
- "","","","",
+ "Disable non-json MQTT response",
+ "Enable light fading at start/power on",
+ "","",
"","","","",
"","","","",
"","","","",
@@ -199,7 +201,7 @@ a_features = [[
"USE_AHT1x","USE_WEMOS_MOTOR_V1","USE_DEVICE_GROUPS","USE_PWM_DIMMER"
],[
"USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080",
- "","","","",
+ "USE_IAQ","USE_DISPLAY_SEVENSEG","USE_AS3935","USE_PING",
"","","","",
"","","","",
"","","","",
@@ -239,7 +241,7 @@ else:
obj = json.load(fp)
def StartDecode():
- print ("\n*** decode-status.py v20200314 by Theo Arends and Jacek Ziolkowski ***")
+ print ("\n*** decode-status.py v20200411 by Theo Arends and Jacek Ziolkowski ***")
# print("Decoding\n{}".format(obj))