Merge pull request #6145 from s-hadinger/IRremote_2_6_10

Upgrade library IRRemoteEsp8266 to 2.6.4, now using sendPioneer()
This commit is contained in:
Theo Arends 2019-07-29 09:40:22 +02:00 committed by GitHub
commit 3bf6e2eb5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
212 changed files with 2395 additions and 350 deletions

View File

@ -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 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. [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.6.3 Now Available ## v2.6.4 Now Available
Version 2.6.3 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. Version 2.6.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.
#### Upgrading from pre-v2.0 #### 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. 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.

View File

@ -1,5 +1,33 @@
# Release Notes # Release Notes
## _v2.6.4 (20190726)_
**[Bug Fixes]**
- Fix some swing problems with the Mitsubishi HAVC protocol (#831)
- Fix parameter ordering for Gree in common a/c code. (#815)
- Fix parameters for Coolix in IRac::sendAc() (#829)
- IRMQTTServer: Fix sending >64 bit codes. (#811)
**[Features]**
- Daikin128: Full detailed support & common a/c support. (#832)
- Midea: Support native temp units of Celsius & SwingV. (#823)
- Gree: Support `YBOFB` models and bug fix. (#815)
- Pioneer: Fix sendPioneer with Pioneer specific timings (#830)
- Daikin128: Initial support for Daikin 17 Series/BRC52B63 (#828)
- Coolix: Better `toCommon()` support. (#825)
- Experimental detailed support for Daikin 176 bits (#816)
- Add setting of output options to A/C classes. (#808)
- Add invert flag support to Samsung AC (#807)
**[Misc]**
- Daikin176: making some change on Daikin176 to work with IRMQTTServer (#826)
- Reduce duplicate code to save (3K+) space. (#813)
- Daikin176: Experiment Daikin176bits with IRMQTTServer (#824)
- Update platformio.ini files for PlatformIO v4.0.0 (#812)
- Change repo URLs to new location. (#806)
- Move `htmlEscape()` to the IRutils namespace (#801)
## _v2.6.3 (20190704)_ ## _v2.6.3 (20190704)_
**[Bug Fixes]** **[Bug Fixes]**

View File

@ -1,6 +1,6 @@
<!--- WARNING: Do NOT edit this file directly. <!--- WARNING: Do NOT edit this file directly.
It is generated by './tools/scrape_supported_devices.py'. It is generated by './tools/scrape_supported_devices.py'.
Last generated: Thu Jul 4 13:48:54 2019 ---> Last generated: Fri Jul 26 17:01:16 2019 --->
# IR Protocols supported by this library # IR Protocols supported by this library
| Protocol | Brand | Model | A/C Model | Detailed A/C Support | | Protocol | Brand | Model | A/C Model | Detailed A/C Support |
@ -10,7 +10,7 @@
| [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **Carrier/Surrey** | 42QG5A55970 remote<BR>53NGK009/012 Inverter<BR>619EGX0090E0 A/C<BR>619EGX0120E0 A/C<BR>619EGX0180E0 A/C<BR>619EGX0220E0 A/C | | - | | [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **Carrier/Surrey** | 42QG5A55970 remote<BR>53NGK009/012 Inverter<BR>619EGX0090E0 A/C<BR>619EGX0120E0 A/C<BR>619EGX0180E0 A/C<BR>619EGX0220E0 A/C | | - |
| [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<BR>BINR 070/071 split-type A/C<BR>RG57K7(B)/BGEF Remote<BR>RG57K7(B)/BGEF 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<BR>BINR 070/071 split-type A/C<BR>RG57K7(B)/BGEF Remote<BR>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<BR>MS12FU-10HRDN1-QRD0GW(B) A/C<BR>MSABAU-07HRFN1-QRD0GW A/C (circa 2016)<BR>MSABAU-07HRFN1-QRD0GW A/C (circa 2016)<BR>RG52D/BGE Remote<BR>RG52D/BGE 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<BR>MS12FU-10HRDN1-QRD0GW(B) A/C<BR>MSABAU-07HRFN1-QRD0GW A/C (circa 2016)<BR>MSABAU-07HRFN1-QRD0GW A/C (circa 2016)<BR>RG52D/BGE Remote<BR>RG52D/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)** | ARC423A5 remote<BR>ARC433** remote<BR>ARC433B69 remote<BR>ARC477A1 remote<BR>FTE12HV2S A/C<BR>FTXZ25NV1B A/C<BR>FTXZ35NV1B A/C<BR>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)<BR>ARC423A5 remote<BR>ARC433** remote<BR>ARC433B69 remote<BR>ARC477A1 remote<BR>BRC4C153 remote<BR>BRC52B63 remote (DAIKIN128)<BR>FTE12HV2S A/C<BR>FTXB09AXVJU A/C (DAIKIN128)<BR>FTXB12AXVJU A/C (DAIKIN128)<BR>FTXZ25NV1B A/C<BR>FTXZ35NV1B A/C<BR>FTXZ50NV1B A/C | | Yes |
| [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Unknown** | | | - | | [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 | | - | | [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<BR>YKR-T/011 remote | | Yes | | [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<BR>YKR-T/011 remote | | Yes |
@ -19,13 +19,15 @@
| [GICable](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GICable.cpp) | **Unknown** | | | - | | [GICable](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GICable.cpp) | **Unknown** | | | - |
| [GlobalCache](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GlobalCache.cpp) | **Unknown** | | | - | | [GlobalCache](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GlobalCache.cpp) | **Unknown** | | | - |
| [Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.cpp) | **[Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.h)** | ZH/JT-03 remote | | Yes | | [Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.cpp) | **[Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.h)** | ZH/JT-03 remote | | Yes |
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[EKOKAI](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | A/C | | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[EKOKAI](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | A/C | YAW1F<BR>YBOFB | Yes |
| [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<BR>YAW1F remote | | Yes | | [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Green](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | YBOFB remote<BR>YBOFB2 remote | YAW1F<BR>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 | | Yes | | [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<BR>YAW1F remote | YAW1F<BR>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<BR>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<BR>HSU07-HEA03 remote<BR>YR-W02 remote | | 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<BR>HSU07-HEA03 remote<BR>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<BR>RAS-35THA6 remote<BR>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)** | LT0541-HTA remote<BR>RAS-35THA6 remote<BR>Series VI A/C (Circa 2007) | | Yes |
| [Inax](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Inax.cpp) | **Lixil** | Inax DT-BA283 Toilet | | - | | [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** | | | - | | [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 |
| [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | KSV26CRC A/C<BR>KSV26HRC A/C<BR>KSV35CRC A/C<BR>KSV35HRC A/C<BR>KSV53HRC A/C<BR>KSV62HRC A/C<BR>KSV70CRC A/C<BR>KSV70HRC A/C<BR>KSV80HRC A/C<BR>YALIF Remote | | Yes | | [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | KSV26CRC A/C<BR>KSV26HRC A/C<BR>KSV35CRC A/C<BR>KSV35HRC A/C<BR>KSV53HRC A/C<BR>KSV62HRC A/C<BR>KSV70CRC A/C<BR>KSV70HRC A/C<BR>KSV80HRC A/C<BR>YALIF Remote | | Yes |
| [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711A20083V remote<BR>6711A20083V remote<BR>AKB74395308 remote<BR>AKB74395308 remote | | Yes | | [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711A20083V remote<BR>6711A20083V remote<BR>AKB74395308 remote<BR>AKB74395308 remote | | Yes |
| [Lasertag](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lasertag.cpp) | **Unknown** | | | - | | [Lasertag](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lasertag.cpp) | **Unknown** | | | - |
@ -33,6 +35,8 @@
| [Lutron](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lutron.cpp) | **Unknown** | | | - | | [Lutron](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lutron.cpp) | **Unknown** | | | - |
| [MWM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MWM.cpp) | **Unknown** | | | - | | [MWM](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MWM.cpp) | **Unknown** | | | - |
| [Magiquest](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.cpp) | **[Unknown](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.h)** | | | Yes | | [Magiquest](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.cpp) | **[Unknown](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Magiquest.h)** | | | Yes |
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Comfee](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | MPD1-12CRN7 A/C | | Yes |
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Keystone](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RG57H4(B)BGEF remote | | Yes |
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Pioneer System](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RUBO18GMFILCAD A/C (18K BTU)<BR>RYBO12GMFILCAD A/C (12K BTU) | | Yes | | [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Pioneer System](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RUBO18GMFILCAD A/C (18K BTU)<BR>RYBO12GMFILCAD A/C (12K BTU) | | Yes |
| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | HC3000 Projector<BR>TV | | Yes | | [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | HC3000 Projector<BR>TV | | Yes |
| [MitsubishiHeavy](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.cpp) | **[Mitsubishi Heavy Industries](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.h)** | RKX502A001C remote<BR>RLA502A700B remote<BR>SRKxxZJ-S A/C<BR>SRKxxZM-S A/C<BR>SRKxxZMXA-S A/C | | Yes | | [MitsubishiHeavy](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.cpp) | **[Mitsubishi Heavy Industries](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_MitsubishiHeavy.h)** | RKX502A001C remote<BR>RLA502A700B remote<BR>SRKxxZJ-S A/C<BR>SRKxxZM-S A/C<BR>SRKxxZMXA-S A/C | | Yes |
@ -73,7 +77,9 @@
- CARRIER_AC - CARRIER_AC
- COOLIX - COOLIX
- DAIKIN - DAIKIN
- DAIKIN128
- DAIKIN160 - DAIKIN160
- DAIKIN176
- DAIKIN2 - DAIKIN2
- DAIKIN216 - DAIKIN216
- DENON - DENON

View File

@ -206,7 +206,7 @@ const uint8_t kPasswordLength = 20;
// ----------------- End of User Configuration Section ------------------------- // ----------------- End of User Configuration Section -------------------------
// Constants // Constants
#define _MY_VERSION_ "v1.3.2-testing" #define _MY_VERSION_ "v1.3.3"
const uint8_t kRebootTime = 15; // Seconds const uint8_t kRebootTime = 15; // Seconds
const uint8_t kQuickDisplayTime = 2; // Seconds const uint8_t kQuickDisplayTime = 2; // Seconds

View File

@ -735,6 +735,7 @@ void handleRoot(void) {
"<select name='type'>" "<select name='type'>"
"<option value='27'>Argo</option>" "<option value='27'>Argo</option>"
"<option value='16'>Daikin (35 bytes)</option>" "<option value='16'>Daikin (35 bytes)</option>"
"<option value='68'>Daikin128 (16 bytes)</option>"
"<option value='65'>Daikin160 (20 bytes)</option>" "<option value='65'>Daikin160 (20 bytes)</option>"
"<option value='67'>Daikin176 (22 bytes)</option>" "<option value='67'>Daikin176 (22 bytes)</option>"
"<option value='53'>Daikin2 (39 bytes)</option>" "<option value='53'>Daikin2 (39 bytes)</option>"

View File

@ -22,7 +22,9 @@
IRArgoAC KEYWORD1 IRArgoAC KEYWORD1
IRCoolixAC KEYWORD1 IRCoolixAC KEYWORD1
IRDaikin128 KEYWORD1
IRDaikin160 KEYWORD1 IRDaikin160 KEYWORD1
IRDaikin176 KEYWORD1
IRDaikin2 KEYWORD1 IRDaikin2 KEYWORD1
IRDaikin216 KEYWORD1 IRDaikin216 KEYWORD1
IRDaikinESP KEYWORD1 IRDaikinESP KEYWORD1
@ -57,6 +59,7 @@ decode_results KEYWORD1
decode_type_t KEYWORD1 decode_type_t KEYWORD1
fanspeed_t KEYWORD1 fanspeed_t KEYWORD1
fujitsu_ac_remote_model_t KEYWORD1 fujitsu_ac_remote_model_t KEYWORD1
gree_ac_remote_model_t KEYWORD1
irparams_t KEYWORD1 irparams_t KEYWORD1
match_result_t KEYWORD1 match_result_t KEYWORD1
opmode_t KEYWORD1 opmode_t KEYWORD1
@ -74,17 +77,24 @@ _delayMicroseconds KEYWORD2
_matchGeneric KEYWORD2 _matchGeneric KEYWORD2
_setMode KEYWORD2 _setMode KEYWORD2
_setTemp KEYWORD2 _setTemp KEYWORD2
acBoolToString KEYWORD2
acModeToString KEYWORD2
add KEYWORD2 add KEYWORD2
addBoolToString KEYWORD2
addFanToString KEYWORD2
addIntToString KEYWORD2
addLabeledString KEYWORD2
addModeToString KEYWORD2
addTempToString KEYWORD2
argo KEYWORD2 argo KEYWORD2
bcdToUint8 KEYWORD2
begin KEYWORD2 begin KEYWORD2
boolToString KEYWORD2 boolToString KEYWORD2
buildFromState KEYWORD2 buildFromState KEYWORD2
buildState KEYWORD2 buildState KEYWORD2
calcBlockChecksum KEYWORD2 calcBlockChecksum KEYWORD2
calcChecksum KEYWORD2 calcChecksum KEYWORD2
calcFirstChecksum KEYWORD2
calcLGChecksum KEYWORD2 calcLGChecksum KEYWORD2
calcSecondChecksum KEYWORD2
calcUSecPeriod KEYWORD2 calcUSecPeriod KEYWORD2
calculateChecksum KEYWORD2 calculateChecksum KEYWORD2
calibrate KEYWORD2 calibrate KEYWORD2
@ -108,7 +118,9 @@ coolix KEYWORD2
copyIrParams KEYWORD2 copyIrParams KEYWORD2
countBits KEYWORD2 countBits KEYWORD2
daikin KEYWORD2 daikin KEYWORD2
daikin128 KEYWORD2
daikin160 KEYWORD2 daikin160 KEYWORD2
daikin176 KEYWORD2
daikin2 KEYWORD2 daikin2 KEYWORD2
daikin216 KEYWORD2 daikin216 KEYWORD2
decode KEYWORD2 decode KEYWORD2
@ -118,7 +130,9 @@ decodeCOOLIX KEYWORD2
decodeCarrierAC KEYWORD2 decodeCarrierAC KEYWORD2
decodeDISH KEYWORD2 decodeDISH KEYWORD2
decodeDaikin KEYWORD2 decodeDaikin KEYWORD2
decodeDaikin128 KEYWORD2
decodeDaikin160 KEYWORD2 decodeDaikin160 KEYWORD2
decodeDaikin176 KEYWORD2
decodeDaikin2 KEYWORD2 decodeDaikin2 KEYWORD2
decodeDaikin216 KEYWORD2 decodeDaikin216 KEYWORD2
decodeDenon KEYWORD2 decodeDenon KEYWORD2
@ -234,6 +248,7 @@ getIon KEYWORD2
getIonFilter KEYWORD2 getIonFilter KEYWORD2
getLed KEYWORD2 getLed KEYWORD2
getLight KEYWORD2 getLight KEYWORD2
getLightToggle KEYWORD2
getMax KEYWORD2 getMax KEYWORD2
getMode KEYWORD2 getMode KEYWORD2
getMold KEYWORD2 getMold KEYWORD2
@ -269,6 +284,7 @@ getSwing KEYWORD2
getSwingH KEYWORD2 getSwingH KEYWORD2
getSwingHorizontal KEYWORD2 getSwingHorizontal KEYWORD2
getSwingV KEYWORD2 getSwingV KEYWORD2
getSwingVToggle KEYWORD2
getSwingVertical KEYWORD2 getSwingVertical KEYWORD2
getSwingVerticalAuto KEYWORD2 getSwingVerticalAuto KEYWORD2
getSwingVerticalPosition KEYWORD2 getSwingVerticalPosition KEYWORD2
@ -278,9 +294,11 @@ getTempRaw KEYWORD2
getTime KEYWORD2 getTime KEYWORD2
getTimer KEYWORD2 getTimer KEYWORD2
getTurbo KEYWORD2 getTurbo KEYWORD2
getUseCelsius KEYWORD2
getVane KEYWORD2 getVane KEYWORD2
getWeeklyTimerEnable KEYWORD2 getWeeklyTimerEnable KEYWORD2
getWiFi KEYWORD2 getWiFi KEYWORD2
getWideVane KEYWORD2
getXFan KEYWORD2 getXFan KEYWORD2
getZoneFollow KEYWORD2 getZoneFollow KEYWORD2
getiFeel KEYWORD2 getiFeel KEYWORD2
@ -298,6 +316,7 @@ isOnTimerActive KEYWORD2
isOnTimerEnabled KEYWORD2 isOnTimerEnabled KEYWORD2
isProtocolSupported KEYWORD2 isProtocolSupported KEYWORD2
isSpecialState KEYWORD2 isSpecialState KEYWORD2
isSwingVToggle KEYWORD2
isTimeCommand KEYWORD2 isTimeCommand KEYWORD2
isTimerActive KEYWORD2 isTimerActive KEYWORD2
isTimerEnabled KEYWORD2 isTimerEnabled KEYWORD2
@ -314,16 +333,17 @@ matchMark KEYWORD2
matchSpace KEYWORD2 matchSpace KEYWORD2
midea KEYWORD2 midea KEYWORD2
minRepeats KEYWORD2 minRepeats KEYWORD2
minsToString KEYWORD2
mitsubishi KEYWORD2 mitsubishi KEYWORD2
mitsubishiHeavy152 KEYWORD2 mitsubishiHeavy152 KEYWORD2
mitsubishiHeavy88 KEYWORD2 mitsubishiHeavy88 KEYWORD2
msToString KEYWORD2
neoclima KEYWORD2 neoclima KEYWORD2
off KEYWORD2 off KEYWORD2
on KEYWORD2 on KEYWORD2
opmodeToString KEYWORD2 opmodeToString KEYWORD2
panasonic KEYWORD2 panasonic KEYWORD2
recoverSavedState KEYWORD2 recoverSavedState KEYWORD2
renderTime KEYWORD2
reset KEYWORD2 reset KEYWORD2
resultAcToString KEYWORD2 resultAcToString KEYWORD2
resultToHexidecimal KEYWORD2 resultToHexidecimal KEYWORD2
@ -342,7 +362,9 @@ sendCOOLIX KEYWORD2
sendCarrierAC KEYWORD2 sendCarrierAC KEYWORD2
sendDISH KEYWORD2 sendDISH KEYWORD2
sendDaikin KEYWORD2 sendDaikin KEYWORD2
sendDaikin128 KEYWORD2
sendDaikin160 KEYWORD2 sendDaikin160 KEYWORD2
sendDaikin176 KEYWORD2
sendDaikin2 KEYWORD2 sendDaikin2 KEYWORD2
sendDaikin216 KEYWORD2 sendDaikin216 KEYWORD2
sendData KEYWORD2 sendData KEYWORD2
@ -438,6 +460,7 @@ setIon KEYWORD2
setIonFilter KEYWORD2 setIonFilter KEYWORD2
setLed KEYWORD2 setLed KEYWORD2
setLight KEYWORD2 setLight KEYWORD2
setLightToggle KEYWORD2
setMax KEYWORD2 setMax KEYWORD2
setMode KEYWORD2 setMode KEYWORD2
setModel KEYWORD2 setModel KEYWORD2
@ -445,8 +468,10 @@ setMold KEYWORD2
setNight KEYWORD2 setNight KEYWORD2
setOffTimer KEYWORD2 setOffTimer KEYWORD2
setOffTimerActive KEYWORD2 setOffTimerActive KEYWORD2
setOffTimerEnabled KEYWORD2
setOnTimer KEYWORD2 setOnTimer KEYWORD2
setOnTimerActive KEYWORD2 setOnTimerActive KEYWORD2
setOnTimerEnabled KEYWORD2
setOutsideQuiet KEYWORD2 setOutsideQuiet KEYWORD2
setPower KEYWORD2 setPower KEYWORD2
setPowerToggle KEYWORD2 setPowerToggle KEYWORD2
@ -468,6 +493,7 @@ setSwing KEYWORD2
setSwingH KEYWORD2 setSwingH KEYWORD2
setSwingHorizontal KEYWORD2 setSwingHorizontal KEYWORD2
setSwingV KEYWORD2 setSwingV KEYWORD2
setSwingVToggle KEYWORD2
setSwingVertical KEYWORD2 setSwingVertical KEYWORD2
setTemp KEYWORD2 setTemp KEYWORD2
setTempRaw KEYWORD2 setTempRaw KEYWORD2
@ -476,9 +502,11 @@ setTimer KEYWORD2
setTimerActive KEYWORD2 setTimerActive KEYWORD2
setTurbo KEYWORD2 setTurbo KEYWORD2
setUnknownThreshold KEYWORD2 setUnknownThreshold KEYWORD2
setUseCelsius KEYWORD2
setVane KEYWORD2 setVane KEYWORD2
setWeeklyTimerEnable KEYWORD2 setWeeklyTimerEnable KEYWORD2
setWiFi KEYWORD2 setWiFi KEYWORD2
setWideVane KEYWORD2
setXFan KEYWORD2 setXFan KEYWORD2
setZoneFollow KEYWORD2 setZoneFollow KEYWORD2
setiFeel KEYWORD2 setiFeel KEYWORD2
@ -491,13 +519,13 @@ strToBool KEYWORD2
strToDecodeType KEYWORD2 strToDecodeType KEYWORD2
strToModel KEYWORD2 strToModel KEYWORD2
sumBytes KEYWORD2 sumBytes KEYWORD2
sumNibbles KEYWORD2
swinghToString KEYWORD2 swinghToString KEYWORD2
swingvToString KEYWORD2 swingvToString KEYWORD2
tcl112 KEYWORD2 tcl112 KEYWORD2
teco KEYWORD2 teco KEYWORD2
ticksHigh KEYWORD2 ticksHigh KEYWORD2
ticksLow KEYWORD2 ticksLow KEYWORD2
timeToString KEYWORD2
toString KEYWORD2 toString KEYWORD2
toggleRC5 KEYWORD2 toggleRC5 KEYWORD2
toggleRC6 KEYWORD2 toggleRC6 KEYWORD2
@ -507,6 +535,7 @@ toshiba KEYWORD2
trotec KEYWORD2 trotec KEYWORD2
typeToString KEYWORD2 typeToString KEYWORD2
uint64ToString KEYWORD2 uint64ToString KEYWORD2
uint8ToBcd KEYWORD2
updateSavedState KEYWORD2 updateSavedState KEYWORD2
validChecksum KEYWORD2 validChecksum KEYWORD2
vestel KEYWORD2 vestel KEYWORD2
@ -553,7 +582,9 @@ CARRIER_AC_BITS LITERAL1
COOLIX LITERAL1 COOLIX LITERAL1
COOLIX_BITS LITERAL1 COOLIX_BITS LITERAL1
DAIKIN LITERAL1 DAIKIN LITERAL1
DAIKIN128 LITERAL1
DAIKIN160 LITERAL1 DAIKIN160 LITERAL1
DAIKIN176 LITERAL1
DAIKIN2 LITERAL1 DAIKIN2 LITERAL1
DAIKIN216 LITERAL1 DAIKIN216 LITERAL1
DAIKIN_AUTO LITERAL1 DAIKIN_AUTO LITERAL1
@ -574,7 +605,9 @@ DECODE_ARGO LITERAL1
DECODE_CARRIER_AC LITERAL1 DECODE_CARRIER_AC LITERAL1
DECODE_COOLIX LITERAL1 DECODE_COOLIX LITERAL1
DECODE_DAIKIN LITERAL1 DECODE_DAIKIN LITERAL1
DECODE_DAIKIN128 LITERAL1
DECODE_DAIKIN160 LITERAL1 DECODE_DAIKIN160 LITERAL1
DECODE_DAIKIN176 LITERAL1
DECODE_DAIKIN2 LITERAL1 DECODE_DAIKIN2 LITERAL1
DECODE_DAIKIN216 LITERAL1 DECODE_DAIKIN216 LITERAL1
DECODE_DENON LITERAL1 DECODE_DENON LITERAL1
@ -860,7 +893,9 @@ SEND_ARGO LITERAL1
SEND_CARRIER_AC LITERAL1 SEND_CARRIER_AC LITERAL1
SEND_COOLIX LITERAL1 SEND_COOLIX LITERAL1
SEND_DAIKIN LITERAL1 SEND_DAIKIN LITERAL1
SEND_DAIKIN128 LITERAL1
SEND_DAIKIN160 LITERAL1 SEND_DAIKIN160 LITERAL1
SEND_DAIKIN176 LITERAL1
SEND_DAIKIN2 LITERAL1 SEND_DAIKIN2 LITERAL1
SEND_DAIKIN216 LITERAL1 SEND_DAIKIN216 LITERAL1
SEND_DENON LITERAL1 SEND_DENON LITERAL1
@ -958,6 +993,8 @@ VESTEL_AC LITERAL1
WHIRLPOOL_AC LITERAL1 WHIRLPOOL_AC LITERAL1
WHYNTER LITERAL1 WHYNTER LITERAL1
WHYNTER_BITS LITERAL1 WHYNTER_BITS LITERAL1
YAW1F LITERAL1
YBOFB LITERAL1
kAiwaRcT501Bits LITERAL1 kAiwaRcT501Bits LITERAL1
kAiwaRcT501MinRepeats LITERAL1 kAiwaRcT501MinRepeats LITERAL1
kAiwaRcT501PostBits LITERAL1 kAiwaRcT501PostBits LITERAL1
@ -1066,6 +1103,54 @@ kCoolixUnknown LITERAL1
kCoolixZeroSpace LITERAL1 kCoolixZeroSpace LITERAL1
kCoolixZeroSpaceTicks LITERAL1 kCoolixZeroSpaceTicks LITERAL1
kCoolixZoneFollowMask LITERAL1 kCoolixZoneFollowMask LITERAL1
kDaikin128Auto LITERAL1
kDaikin128BitCeiling LITERAL1
kDaikin128BitEcono LITERAL1
kDaikin128BitHalfHour LITERAL1
kDaikin128BitMark LITERAL1
kDaikin128BitPowerToggle LITERAL1
kDaikin128BitSleep LITERAL1
kDaikin128BitSwing LITERAL1
kDaikin128BitTimerEnabled LITERAL1
kDaikin128BitWall LITERAL1
kDaikin128Bits LITERAL1
kDaikin128ByteClockHours LITERAL1
kDaikin128ByteClockMins LITERAL1
kDaikin128ByteEconoLight LITERAL1
kDaikin128ByteModeFan LITERAL1
kDaikin128ByteOffTimer LITERAL1
kDaikin128ByteOnTimer LITERAL1
kDaikin128BytePowerSwingSleep LITERAL1
kDaikin128ByteTemp LITERAL1
kDaikin128Cool LITERAL1
kDaikin128DefaultRepeat LITERAL1
kDaikin128Dry LITERAL1
kDaikin128Fan LITERAL1
kDaikin128FanAuto LITERAL1
kDaikin128FanHigh LITERAL1
kDaikin128FanLow LITERAL1
kDaikin128FanMed LITERAL1
kDaikin128FanPowerful LITERAL1
kDaikin128FanQuiet LITERAL1
kDaikin128FooterMark LITERAL1
kDaikin128Freq LITERAL1
kDaikin128Gap LITERAL1
kDaikin128HdrMark LITERAL1
kDaikin128HdrSpace LITERAL1
kDaikin128Heat LITERAL1
kDaikin128LeaderMark LITERAL1
kDaikin128LeaderSpace LITERAL1
kDaikin128MaskFan LITERAL1
kDaikin128MaskHours LITERAL1
kDaikin128MaskLight LITERAL1
kDaikin128MaskMode LITERAL1
kDaikin128MaxTemp LITERAL1
kDaikin128MinTemp LITERAL1
kDaikin128OneSpace LITERAL1
kDaikin128SectionLength LITERAL1
kDaikin128Sections LITERAL1
kDaikin128StateLength LITERAL1
kDaikin128ZeroSpace LITERAL1
kDaikin160BitMark LITERAL1 kDaikin160BitMark LITERAL1
kDaikin160Bits LITERAL1 kDaikin160Bits LITERAL1
kDaikin160ByteFan LITERAL1 kDaikin160ByteFan LITERAL1
@ -1094,6 +1179,35 @@ kDaikin160SwingVLow LITERAL1
kDaikin160SwingVLowest LITERAL1 kDaikin160SwingVLowest LITERAL1
kDaikin160SwingVMiddle LITERAL1 kDaikin160SwingVMiddle LITERAL1
kDaikin160ZeroSpace LITERAL1 kDaikin160ZeroSpace LITERAL1
kDaikin176BitMark LITERAL1
kDaikin176Bits LITERAL1
kDaikin176ByteFan LITERAL1
kDaikin176ByteMode LITERAL1
kDaikin176ByteModeButton LITERAL1
kDaikin176BytePower LITERAL1
kDaikin176ByteSwingH LITERAL1
kDaikin176ByteTemp LITERAL1
kDaikin176Cool LITERAL1
kDaikin176DefaultRepeat LITERAL1
kDaikin176DryFanTemp LITERAL1
kDaikin176FanMax LITERAL1
kDaikin176Freq LITERAL1
kDaikin176Gap LITERAL1
kDaikin176HdrMark LITERAL1
kDaikin176HdrSpace LITERAL1
kDaikin176MaskFan LITERAL1
kDaikin176MaskMode LITERAL1
kDaikin176MaskSwingH LITERAL1
kDaikin176MaskTemp LITERAL1
kDaikin176ModeButton LITERAL1
kDaikin176OneSpace LITERAL1
kDaikin176Section1Length LITERAL1
kDaikin176Section2Length LITERAL1
kDaikin176Sections LITERAL1
kDaikin176StateLength LITERAL1
kDaikin176SwingHAuto LITERAL1
kDaikin176SwingHOff LITERAL1
kDaikin176ZeroSpace LITERAL1
kDaikin216BitMark LITERAL1 kDaikin216BitMark LITERAL1
kDaikin216Bits LITERAL1 kDaikin216Bits LITERAL1
kDaikin216ByteFan LITERAL1 kDaikin216ByteFan LITERAL1
@ -1203,6 +1317,7 @@ kDaikinDry LITERAL1
kDaikinFan LITERAL1 kDaikinFan LITERAL1
kDaikinFanAuto LITERAL1 kDaikinFanAuto LITERAL1
kDaikinFanMax LITERAL1 kDaikinFanMax LITERAL1
kDaikinFanMed LITERAL1
kDaikinFanMin LITERAL1 kDaikinFanMin LITERAL1
kDaikinFanQuiet LITERAL1 kDaikinFanQuiet LITERAL1
kDaikinFirstHeader64 LITERAL1 kDaikinFirstHeader64 LITERAL1
@ -1412,6 +1527,7 @@ kGreeFan LITERAL1
kGreeFanAuto LITERAL1 kGreeFanAuto LITERAL1
kGreeFanMask LITERAL1 kGreeFanMask LITERAL1
kGreeFanMax LITERAL1 kGreeFanMax LITERAL1
kGreeFanMed LITERAL1
kGreeFanMin LITERAL1 kGreeFanMin LITERAL1
kGreeHdrMark LITERAL1 kGreeHdrMark LITERAL1
kGreeHdrSpace LITERAL1 kGreeHdrSpace LITERAL1
@ -1537,6 +1653,7 @@ kHitachiAcFan LITERAL1
kHitachiAcFanAuto LITERAL1 kHitachiAcFanAuto LITERAL1
kHitachiAcFanHigh LITERAL1 kHitachiAcFanHigh LITERAL1
kHitachiAcFanLow LITERAL1 kHitachiAcFanLow LITERAL1
kHitachiAcFanMed LITERAL1
kHitachiAcHdrMark LITERAL1 kHitachiAcHdrMark LITERAL1
kHitachiAcHdrSpace LITERAL1 kHitachiAcHdrSpace LITERAL1
kHitachiAcHeat LITERAL1 kHitachiAcHeat LITERAL1
@ -1589,6 +1706,7 @@ kKelvinatorFan LITERAL1
kKelvinatorFanAuto LITERAL1 kKelvinatorFanAuto LITERAL1
kKelvinatorFanMask LITERAL1 kKelvinatorFanMask LITERAL1
kKelvinatorFanMax LITERAL1 kKelvinatorFanMax LITERAL1
kKelvinatorFanMin LITERAL1
kKelvinatorFanOffset LITERAL1 kKelvinatorFanOffset LITERAL1
kKelvinatorGapSpace LITERAL1 kKelvinatorGapSpace LITERAL1
kKelvinatorGapSpaceTicks LITERAL1 kKelvinatorGapSpaceTicks LITERAL1
@ -1702,6 +1820,7 @@ kMaxTimeoutMs LITERAL1
kMedium LITERAL1 kMedium LITERAL1
kMiddle LITERAL1 kMiddle LITERAL1
kMideaACAuto LITERAL1 kMideaACAuto LITERAL1
kMideaACCelsiusBit LITERAL1
kMideaACChecksumMask LITERAL1 kMideaACChecksumMask LITERAL1
kMideaACCool LITERAL1 kMideaACCool LITERAL1
kMideaACDry LITERAL1 kMideaACDry LITERAL1
@ -1721,6 +1840,7 @@ kMideaACPower LITERAL1
kMideaACSleep LITERAL1 kMideaACSleep LITERAL1
kMideaACStateMask LITERAL1 kMideaACStateMask LITERAL1
kMideaACTempMask LITERAL1 kMideaACTempMask LITERAL1
kMideaACToggleSwingV LITERAL1
kMideaBitMark LITERAL1 kMideaBitMark LITERAL1
kMideaBitMarkTicks LITERAL1 kMideaBitMarkTicks LITERAL1
kMideaBits LITERAL1 kMideaBits LITERAL1
@ -1753,6 +1873,7 @@ kMitsubishiAcCool LITERAL1
kMitsubishiAcDry LITERAL1 kMitsubishiAcDry LITERAL1
kMitsubishiAcFanAuto LITERAL1 kMitsubishiAcFanAuto LITERAL1
kMitsubishiAcFanMax LITERAL1 kMitsubishiAcFanMax LITERAL1
kMitsubishiAcFanQuiet LITERAL1
kMitsubishiAcFanRealMax LITERAL1 kMitsubishiAcFanRealMax LITERAL1
kMitsubishiAcFanSilent LITERAL1 kMitsubishiAcFanSilent LITERAL1
kMitsubishiAcHdrMark LITERAL1 kMitsubishiAcHdrMark LITERAL1
@ -1770,6 +1891,7 @@ kMitsubishiAcStartTimer LITERAL1
kMitsubishiAcStopTimer LITERAL1 kMitsubishiAcStopTimer LITERAL1
kMitsubishiAcVaneAuto LITERAL1 kMitsubishiAcVaneAuto LITERAL1
kMitsubishiAcVaneAutoMove LITERAL1 kMitsubishiAcVaneAutoMove LITERAL1
kMitsubishiAcWideVaneAuto LITERAL1
kMitsubishiAcZeroSpace LITERAL1 kMitsubishiAcZeroSpace LITERAL1
kMitsubishiBitMark LITERAL1 kMitsubishiBitMark LITERAL1
kMitsubishiBitMarkTicks LITERAL1 kMitsubishiBitMarkTicks LITERAL1
@ -1968,6 +2090,7 @@ kPanasonicAcExcess LITERAL1
kPanasonicAcFan LITERAL1 kPanasonicAcFan LITERAL1
kPanasonicAcFanAuto LITERAL1 kPanasonicAcFanAuto LITERAL1
kPanasonicAcFanMax LITERAL1 kPanasonicAcFanMax LITERAL1
kPanasonicAcFanMed LITERAL1
kPanasonicAcFanMin LITERAL1 kPanasonicAcFanMin LITERAL1
kPanasonicAcFanModeTemp LITERAL1 kPanasonicAcFanModeTemp LITERAL1
kPanasonicAcFanOffset LITERAL1 kPanasonicAcFanOffset LITERAL1
@ -2027,7 +2150,22 @@ kPanasonicUnknown LITERAL1
kPanasonicZeroSpace LITERAL1 kPanasonicZeroSpace LITERAL1
kPanasonicZeroSpaceTicks LITERAL1 kPanasonicZeroSpaceTicks LITERAL1
kPeriodOffset LITERAL1 kPeriodOffset LITERAL1
kPioneerBitMark LITERAL1
kPioneerBitMarkTicks LITERAL1
kPioneerBits LITERAL1 kPioneerBits LITERAL1
kPioneerHdrMark LITERAL1
kPioneerHdrMarkTicks LITERAL1
kPioneerHdrSpace LITERAL1
kPioneerHdrSpaceTicks LITERAL1
kPioneerMinCommandLength LITERAL1
kPioneerMinCommandLengthTicks LITERAL1
kPioneerMinGap LITERAL1
kPioneerMinGapTicks LITERAL1
kPioneerOneSpace LITERAL1
kPioneerOneSpaceTicks LITERAL1
kPioneerTick LITERAL1
kPioneerZeroSpace LITERAL1
kPioneerZeroSpaceTicks LITERAL1
kProntoDataOffset LITERAL1 kProntoDataOffset LITERAL1
kProntoFreqFactor LITERAL1 kProntoFreqFactor LITERAL1
kProntoFreqOffset LITERAL1 kProntoFreqOffset LITERAL1
@ -2307,6 +2445,8 @@ kToshibaAcCool LITERAL1
kToshibaAcDry LITERAL1 kToshibaAcDry LITERAL1
kToshibaAcFanAuto LITERAL1 kToshibaAcFanAuto LITERAL1
kToshibaAcFanMax LITERAL1 kToshibaAcFanMax LITERAL1
kToshibaAcFanMed LITERAL1
kToshibaAcFanMin LITERAL1
kToshibaAcHdrMark LITERAL1 kToshibaAcHdrMark LITERAL1
kToshibaAcHdrSpace LITERAL1 kToshibaAcHdrSpace LITERAL1
kToshibaAcHeat LITERAL1 kToshibaAcHeat LITERAL1

View File

@ -1,6 +1,6 @@
{ {
"name": "IRremoteESP8266", "name": "IRremoteESP8266",
"version": "2.6.3", "version": "2.6.4",
"keywords": "infrared, ir, remote, esp8266, esp32", "keywords": "infrared, ir, remote, esp8266, esp32",
"description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)", "description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)",
"repository": "repository":

View File

@ -1,5 +1,5 @@
name=IRremoteESP8266 name=IRremoteESP8266
version=2.6.3 version=2.6.4
author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff
maintainer=Mark Szabo, David Conran, Sebastien Warin, Roi Dayan, Massimiliano Pinto maintainer=Mark Szabo, David Conran, Sebastien Warin, Roi Dayan, Massimiliano Pinto
sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32) sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32)

View File

@ -55,6 +55,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#if SEND_DAIKIN #if SEND_DAIKIN
case decode_type_t::DAIKIN: case decode_type_t::DAIKIN:
#endif #endif
#if SEND_DAIKIN128
case decode_type_t::DAIKIN128:
#endif
#if SEND_DAIKIN160 #if SEND_DAIKIN160
case decode_type_t::DAIKIN160: case decode_type_t::DAIKIN160:
#endif #endif
@ -231,6 +234,32 @@ void IRac::daikin(IRDaikinESP *ac,
} }
#endif // SEND_DAIKIN #endif // SEND_DAIKIN
#if SEND_DAIKIN128
void IRac::daikin128(IRDaikin128 *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 bool light,
const bool econo, const int16_t sleep, const int16_t clock) {
ac->setPowerToggle(on);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setSwingVertical((int8_t)swingv >= 0);
// No Horizontal Swing setting avaliable.
ac->setQuiet(quiet);
ac->setLightToggle(light ? kDaikin128BitWall : 0);
// No Filter setting available.
ac->setPowerful(turbo);
ac->setEcono(econo);
// No Clean setting available.
// No Beep setting available.
ac->setSleep(sleep > 0);
if (clock >= 0) ac->setClock(clock);
ac->send();
}
#endif // SEND_DAIKIN128
#if SEND_DAIKIN160 #if SEND_DAIKIN160
void IRac::daikin160(IRDaikin160 *ac, void IRac::daikin160(IRDaikin160 *ac,
const bool on, const stdAc::opmode_t mode, const bool on, const stdAc::opmode_t mode,
@ -408,11 +437,12 @@ void IRac::goodweather(IRGoodweatherAc *ac,
#endif // SEND_GOODWEATHER #endif // SEND_GOODWEATHER
#if SEND_GREE #if SEND_GREE
void IRac::gree(IRGreeAC *ac, void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode, const float degrees, const bool on, const stdAc::opmode_t mode, const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const bool turbo, const bool light, const bool clean, const bool turbo, const bool light, const bool clean,
const int16_t sleep) { const int16_t sleep) {
ac->setModel(model);
ac->setPower(on); ac->setPower(on);
ac->setMode(ac->convertMode(mode)); ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees); ac->setTemp(degrees);
@ -533,13 +563,15 @@ void IRac::kelvinator(IRKelvinatorAC *ac,
#if SEND_MIDEA #if SEND_MIDEA
void IRac::midea(IRMideaAC *ac, void IRac::midea(IRMideaAC *ac,
const bool on, const stdAc::opmode_t mode, const float degrees, const bool on, const stdAc::opmode_t mode, const bool celsius,
const stdAc::fanspeed_t fan, const int16_t sleep) { const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const int16_t sleep) {
ac->setPower(on); ac->setPower(on);
ac->setMode(ac->convertMode(mode)); ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees, true); // true means use Celsius. ac->setUseCelsius(celsius);
ac->setTemp(degrees, celsius);
ac->setFan(ac->convertFan(fan)); ac->setFan(ac->convertFan(fan));
// No Vertical swing setting available. ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff);
// No Horizontal swing setting available. // No Horizontal swing setting available.
// No Quiet setting available. // No Quiet setting available.
// No Turbo setting available. // No Turbo setting available.
@ -558,13 +590,14 @@ void IRac::mitsubishi(IRMitsubishiAC *ac,
const bool on, const stdAc::opmode_t mode, const bool on, const stdAc::opmode_t mode,
const float degrees, const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet, const int16_t clock) { const bool quiet, const int16_t clock) {
ac->setPower(on); ac->setPower(on);
ac->setMode(ac->convertMode(mode)); ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees); ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan)); ac->setFan(ac->convertFan(fan));
ac->setVane(ac->convertSwingV(swingv)); ac->setVane(ac->convertSwingV(swingv));
// No Horizontal swing setting available. ac->setWideVane(ac->convertSwingH(swingh));
if (quiet) ac->setFan(kMitsubishiAcFanSilent); if (quiet) ac->setFan(kMitsubishiAcFanSilent);
// No Turbo setting available. // No Turbo setting available.
// No Light setting available. // No Light setting available.
@ -911,7 +944,18 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired,
result.turbo = desired.turbo ^ prev->turbo; result.turbo = desired.turbo ^ prev->turbo;
result.light = desired.light ^ prev->light; result.light = desired.light ^ prev->light;
result.clean = desired.clean ^ prev->clean; result.clean = desired.clean ^ prev->clean;
result.sleep = (desired.sleep ^ prev->sleep) ? 0 : -1; result.sleep = ((desired.sleep >= 0) ^ (prev->sleep >= 0)) ? 0 : -1;
break;
case decode_type_t::DAIKIN128:
result.power = desired.power ^ prev->power;
result.light = desired.light ^ prev->light;
break;
case decode_type_t::MIDEA:
if ((desired.swingv == stdAc::swingv_t::kOff) ^
(prev->swingv == stdAc::swingv_t::kOff)) // It changed, so toggle.
result.swingv = stdAc::swingv_t::kAuto;
else
result.swingv = stdAc::swingv_t::kOff; // No change, so no toggle.
break; break;
case decode_type_t::WHIRLPOOL_AC: case decode_type_t::WHIRLPOOL_AC:
result.power = desired.power ^ prev->power; result.power = desired.power ^ prev->power;
@ -977,16 +1021,16 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
argo(&ac, on, mode, degC, fan, swingv, turbo, sleep); argo(&ac, on, mode, degC, fan, swingv, turbo, sleep);
break; break;
} }
#endif // SEND_DAIKIN #endif // SEND_ARGO
#if SEND_COOLIX #if SEND_COOLIX
case COOLIX: case COOLIX:
{ {
IRCoolixAC ac(_pin, _inverted, _modulation); IRCoolixAC ac(_pin, _inverted, _modulation);
coolix(&ac, on, mode, degC, fan, swingv, swingh, coolix(&ac, on, mode, degC, fan, swingv, swingh,
quiet, turbo, econo, clean); turbo, light, clean, sleep);
break; break;
} }
#endif // SEND_DAIKIN #endif // SEND_COOLIX
#if SEND_DAIKIN #if SEND_DAIKIN
case DAIKIN: case DAIKIN:
{ {
@ -996,6 +1040,15 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
break; break;
} }
#endif // SEND_DAIKIN #endif // SEND_DAIKIN
#if SEND_DAIKIN128
case DAIKIN128:
{
IRDaikin128 ac(_pin, _inverted, _modulation);
daikin128(&ac, on, mode, degC, fan, swingv, quiet, turbo,
light, econo, sleep, clock);
break;
}
#endif // SEND_DAIKIN2
#if SEND_DAIKIN160 #if SEND_DAIKIN160
case DAIKIN160: case DAIKIN160:
{ {
@ -1007,7 +1060,7 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
#if SEND_DAIKIN176 #if SEND_DAIKIN176
case DAIKIN176: case DAIKIN176:
{ {
IRDaikin176 ac(_pin); IRDaikin176 ac(_pin, _inverted, _modulation);
daikin176(&ac, on, mode, degC, fan, swingh); daikin176(&ac, on, mode, degC, fan, swingh);
break; break;
} }
@ -1020,7 +1073,7 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
light, econo, filter, clean, beep, sleep, clock); light, econo, filter, clean, beep, sleep, clock);
break; break;
} }
#endif // SEND_DAIKIN216 #endif // SEND_DAIKIN2
#if SEND_DAIKIN216 #if SEND_DAIKIN216
case DAIKIN216: case DAIKIN216:
{ {
@ -1061,9 +1114,10 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
#if SEND_GREE #if SEND_GREE
case GREE: case GREE:
{ {
IRGreeAC ac(_pin, _inverted, _modulation); IRGreeAC ac(_pin, (gree_ac_remote_model_t)model, _inverted, _modulation);
ac.begin(); ac.begin();
gree(&ac, on, mode, degC, fan, swingv, light, turbo, clean, sleep); gree(&ac, (gree_ac_remote_model_t)model, on, mode, degC, fan, swingv,
turbo, light, clean, sleep);
break; break;
} }
#endif // SEND_GREE #endif // SEND_GREE
@ -1109,7 +1163,7 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
{ {
IRMideaAC ac(_pin, _inverted, _modulation); IRMideaAC ac(_pin, _inverted, _modulation);
ac.begin(); ac.begin();
midea(&ac, on, mode, degC, fan, sleep); midea(&ac, on, mode, celsius, degrees, fan, swingv, sleep);
break; break;
} }
#endif // SEND_MIDEA #endif // SEND_MIDEA
@ -1118,7 +1172,7 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
{ {
IRMitsubishiAC ac(_pin, _inverted, _modulation); IRMitsubishiAC ac(_pin, _inverted, _modulation);
ac.begin(); ac.begin();
mitsubishi(&ac, on, mode, degC, fan, swingv, quiet, clock); mitsubishi(&ac, on, mode, degC, fan, swingv, swingh, quiet, clock);
break; break;
} }
#endif // SEND_MITSUBISHI_AC #endif // SEND_MITSUBISHI_AC
@ -1515,6 +1569,13 @@ namespace IRAcUtils {
return ac.toString(); return ac.toString();
} }
#endif // DECODE_DAIKIN #endif // DECODE_DAIKIN
#if DECODE_DAIKIN128
case decode_type_t::DAIKIN128: {
IRDaikin128 ac(0);
ac.setRaw(result->state);
return ac.toString();
}
#endif // DECODE_DAIKIN128
#if DECODE_DAIKIN160 #if DECODE_DAIKIN160
case decode_type_t::DAIKIN160: { case decode_type_t::DAIKIN160: {
IRDaikin160 ac(0); IRDaikin160 ac(0);
@ -1847,7 +1908,7 @@ namespace IRAcUtils {
case decode_type_t::MIDEA: { case decode_type_t::MIDEA: {
IRMideaAC ac(kGpioUnused); IRMideaAC ac(kGpioUnused);
ac.setRaw(decode->value); // Uses value instead of state. ac.setRaw(decode->value); // Uses value instead of state.
*result = ac.toCommon(); *result = ac.toCommon(prev);
break; break;
} }
#endif // DECODE_MIDEA #endif // DECODE_MIDEA

View File

@ -95,6 +95,15 @@ class IRac {
const bool quiet, const bool turbo, const bool econo, const bool quiet, const bool turbo, const bool econo,
const bool clean); const bool clean);
#endif // SEND_DAIKIN #endif // SEND_DAIKIN
#if SEND_DAIKIN128
void daikin128(IRDaikin128 *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 bool light,
const bool econo, const int16_t sleep = -1,
const int16_t clock = -1);
#endif // SEND_DAIKIN128
#if SEND_DAIKIN160 #if SEND_DAIKIN160
void daikin160(IRDaikin160 *ac, void daikin160(IRDaikin160 *ac,
const bool on, const stdAc::opmode_t mode, const bool on, const stdAc::opmode_t mode,
@ -148,7 +157,7 @@ void electra(IRElectraAc *ac,
const int16_t sleep = -1); const int16_t sleep = -1);
#endif // SEND_GOODWEATHER #endif // SEND_GOODWEATHER
#if SEND_GREE #if SEND_GREE
void gree(IRGreeAC *ac, void gree(IRGreeAC *ac, const gree_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode, const float degrees, const bool on, const stdAc::opmode_t mode, const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const bool turbo, const bool light, const bool clean, const bool turbo, const bool light, const bool clean,
@ -185,14 +194,16 @@ void electra(IRElectraAc *ac,
#endif // SEND_KELVINATOR #endif // SEND_KELVINATOR
#if SEND_MIDEA #if SEND_MIDEA
void midea(IRMideaAC *ac, void midea(IRMideaAC *ac,
const bool on, const stdAc::opmode_t mode, const float degrees, const bool on, const stdAc::opmode_t mode, const bool celsius,
const stdAc::fanspeed_t fan, const int16_t sleep = -1); const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const int16_t sleep = -1);
#endif // SEND_MIDEA #endif // SEND_MIDEA
#if SEND_MITSUBISHI_AC #if SEND_MITSUBISHI_AC
void mitsubishi(IRMitsubishiAC *ac, void mitsubishi(IRMitsubishiAC *ac,
const bool on, const stdAc::opmode_t mode, const bool on, const stdAc::opmode_t mode,
const float degrees, const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet, const int16_t clock = -1); const bool quiet, const int16_t clock = -1);
#endif // SEND_MITSUBISHI_AC #endif // SEND_MITSUBISHI_AC
#if SEND_MITSUBISHIHEAVY #if SEND_MITSUBISHIHEAVY

View File

@ -647,6 +647,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) {
DPRINTLN("Attempting Daikin176 decode"); DPRINTLN("Attempting Daikin176 decode");
if (decodeDaikin176(results)) return true; if (decodeDaikin176(results)) return true;
#endif // DECODE_DAIKIN176 #endif // DECODE_DAIKIN176
#if DECODE_DAIKIN128
DPRINTLN("Attempting Daikin128 decode");
if (decodeDaikin128(results)) return true;
#endif // DECODE_DAIKIN128
#if DECODE_HASH #if DECODE_HASH
// decodeHash returns a hash on any input. // decodeHash returns a hash on any input.
// Thus, it needs to be last in the list. // Thus, it needs to be last in the list.

View File

@ -343,15 +343,20 @@ class IRrecv {
bool decodeDaikin(decode_results *results, const uint16_t nbits = kDaikinBits, bool decodeDaikin(decode_results *results, const uint16_t nbits = kDaikinBits,
const bool strict = true); const bool strict = true);
#endif #endif
#if DECODE_DAIKIN128
bool decodeDaikin128(decode_results *results,
const uint16_t nbits = kDaikin128Bits,
const bool strict = true);
#endif // DECODE_DAIKIN128
#if DECODE_DAIKIN160 #if DECODE_DAIKIN160
bool decodeDaikin160(decode_results *results, bool decodeDaikin160(decode_results *results,
const uint16_t nbits = kDaikin160Bits, const uint16_t nbits = kDaikin160Bits,
const bool strict = true); const bool strict = true);
#endif // DECODE_DAIKIN160 #endif // DECODE_DAIKIN160
#if DECODE_DAIKIN176 #if DECODE_DAIKIN176
bool decodeDaikin176(decode_results *results, bool decodeDaikin176(decode_results *results,
const uint16_t nbits = kDaikin176Bits, const uint16_t nbits = kDaikin176Bits,
const bool strict = true); const bool strict = true);
#endif // DECODE_DAIKIN176 #endif // DECODE_DAIKIN176
#if DECODE_DAIKIN2 #if DECODE_DAIKIN2
bool decodeDaikin2(decode_results *results, uint16_t nbits = kDaikin2Bits, bool decodeDaikin2(decode_results *results, uint16_t nbits = kDaikin2Bits,

View File

@ -51,7 +51,7 @@
#endif // UNIT_TEST #endif // UNIT_TEST
// Library Version // Library Version
#define _IRREMOTEESP8266_VERSION_ "2.6.3" #define _IRREMOTEESP8266_VERSION_ "2.6.4"
// Supported IR protocols // Supported IR protocols
// Each protocol you include costs memory and, during decode, costs time // Each protocol you include costs memory and, during decode, costs time
// Disable (set to false) all the protocols you do not need/want! // Disable (set to false) all the protocols you do not need/want!
@ -244,6 +244,9 @@
#define DECODE_DAIKIN176 true #define DECODE_DAIKIN176 true
#define SEND_DAIKIN176 true #define SEND_DAIKIN176 true
#define DECODE_DAIKIN128 true
#define SEND_DAIKIN128 true
*/ */
// Tasmota supported protocols (less protocols is less code size) // Tasmota supported protocols (less protocols is less code size)
@ -434,6 +437,9 @@
#define DECODE_DAIKIN176 false #define DECODE_DAIKIN176 false
#define SEND_DAIKIN176 true #define SEND_DAIKIN176 true
#define DECODE_DAIKIN128 false
#define SEND_DAIKIN128 true
#if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \ #if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \
DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \ DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \
DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \ DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \
@ -442,7 +448,7 @@
DECODE_PANASONIC_AC || DECODE_MWM || DECODE_DAIKIN2 || \ DECODE_PANASONIC_AC || DECODE_MWM || DECODE_DAIKIN2 || \
DECODE_VESTEL_AC || DECODE_TCL112AC || DECODE_MITSUBISHIHEAVY || \ DECODE_VESTEL_AC || DECODE_TCL112AC || DECODE_MITSUBISHIHEAVY || \
DECODE_DAIKIN216 || DECODE_SHARP_AC || DECODE_DAIKIN160 || \ DECODE_DAIKIN216 || DECODE_SHARP_AC || DECODE_DAIKIN160 || \
DECODE_NEOCLIMA || DECODE_DAIKIN176) DECODE_NEOCLIMA || DECODE_DAIKIN176 || DECODE_DAIKIN128)
#define DECODE_AC true // We need some common infrastructure for decoding A/Cs. #define DECODE_AC true // We need some common infrastructure for decoding A/Cs.
#else #else
#define DECODE_AC false // We don't need that infrastructure. #define DECODE_AC false // We don't need that infrastructure.
@ -529,8 +535,9 @@ enum decode_type_t {
DAIKIN160, // 65 DAIKIN160, // 65
NEOCLIMA, NEOCLIMA,
DAIKIN176, DAIKIN176,
DAIKIN128,
// Add new entries before this one, and update it to point to the last entry. // Add new entries before this one, and update it to point to the last entry.
kLastDecodeType = DAIKIN176, kLastDecodeType = DAIKIN128,
}; };
// Message lengths & required repeat values // Message lengths & required repeat values
@ -557,6 +564,9 @@ const uint16_t kDaikin2DefaultRepeat = kNoRepeat;
const uint16_t kDaikin160StateLength = 20; const uint16_t kDaikin160StateLength = 20;
const uint16_t kDaikin160Bits = kDaikin160StateLength * 8; const uint16_t kDaikin160Bits = kDaikin160StateLength * 8;
const uint16_t kDaikin160DefaultRepeat = kNoRepeat; const uint16_t kDaikin160DefaultRepeat = kNoRepeat;
const uint16_t kDaikin128StateLength = 16;
const uint16_t kDaikin128Bits = kDaikin128StateLength * 8;
const uint16_t kDaikin128DefaultRepeat = kNoRepeat;
const uint16_t kDaikin176StateLength = 22; const uint16_t kDaikin176StateLength = 22;
const uint16_t kDaikin176Bits = kDaikin176StateLength * 8; const uint16_t kDaikin176Bits = kDaikin176StateLength * 8;
const uint16_t kDaikin176DefaultRepeat = kNoRepeat; const uint16_t kDaikin176DefaultRepeat = kNoRepeat;

View File

@ -580,10 +580,12 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
return kArgoBits; return kArgoBits;
case DAIKIN: case DAIKIN:
return kDaikinBits; return kDaikinBits;
case DAIKIN128:
return kDaikin128Bits;
case DAIKIN160: case DAIKIN160:
return kDaikin160Bits; return kDaikin160Bits;
case DAIKIN176: case DAIKIN176:
return kDaikin176Bits; return kDaikin176Bits;
case DAIKIN2: case DAIKIN2:
return kDaikin2Bits; return kDaikin2Bits;
case DAIKIN216: case DAIKIN216:
@ -849,15 +851,20 @@ bool IRsend::send(const decode_type_t type, const unsigned char *state,
sendDaikin(state, nbytes); sendDaikin(state, nbytes);
break; break;
#endif // SEND_DAIKIN #endif // SEND_DAIKIN
#if SEND_DAIKIN128
case DAIKIN128:
sendDaikin128(state, nbytes);
break;
#endif // SEND_DAIKIN128
#if SEND_DAIKIN160 #if SEND_DAIKIN160
case DAIKIN160: case DAIKIN160:
sendDaikin160(state, nbytes); sendDaikin160(state, nbytes);
break; break;
#endif // SEND_DAIKIN160 #endif // SEND_DAIKIN160
#if SEND_DAIKIN176 #if SEND_DAIKIN176
case DAIKIN176: case DAIKIN176:
sendDaikin176(state, nbytes); sendDaikin176(state, nbytes);
break; break;
#endif // SEND_DAIKIN176 #endif // SEND_DAIKIN176
#if SEND_DAIKIN2 #if SEND_DAIKIN2
case DAIKIN2: case DAIKIN2:

View File

@ -306,15 +306,20 @@ class IRsend {
const uint16_t nbytes = kDaikinStateLength, const uint16_t nbytes = kDaikinStateLength,
const uint16_t repeat = kDaikinDefaultRepeat); const uint16_t repeat = kDaikinDefaultRepeat);
#endif #endif
#if SEND_DAIKIN128
void sendDaikin128(const unsigned char data[],
const uint16_t nbytes = kDaikin128StateLength,
const uint16_t repeat = kDaikin128DefaultRepeat);
#endif // SEND_DAIKIN128
#if SEND_DAIKIN160 #if SEND_DAIKIN160
void sendDaikin160(const unsigned char data[], void sendDaikin160(const unsigned char data[],
const uint16_t nbytes = kDaikin160StateLength, const uint16_t nbytes = kDaikin160StateLength,
const uint16_t repeat = kDaikin160DefaultRepeat); const uint16_t repeat = kDaikin160DefaultRepeat);
#endif // SEND_DAIKIN160 #endif // SEND_DAIKIN160
#if SEND_DAIKIN176 #if SEND_DAIKIN176
void sendDaikin176(const unsigned char data[], void sendDaikin176(const unsigned char data[],
const uint16_t nbytes = kDaikin176StateLength, const uint16_t nbytes = kDaikin176StateLength,
const uint16_t repeat = kDaikin176DefaultRepeat); const uint16_t repeat = kDaikin176DefaultRepeat);
#endif // SEND_DAIKIN176 #endif // SEND_DAIKIN176
#if SEND_DAIKIN2 #if SEND_DAIKIN2
void sendDaikin2(const unsigned char data[], void sendDaikin2(const unsigned char data[],

View File

@ -103,6 +103,8 @@ decode_type_t strToDecodeType(const char * const str) {
return decode_type_t::COOLIX; return decode_type_t::COOLIX;
else if (!strcasecmp(str, "DAIKIN")) else if (!strcasecmp(str, "DAIKIN"))
return decode_type_t::DAIKIN; return decode_type_t::DAIKIN;
else if (!strcasecmp(str, "DAIKIN128"))
return decode_type_t::DAIKIN128;
else if (!strcasecmp(str, "DAIKIN160")) else if (!strcasecmp(str, "DAIKIN160"))
return decode_type_t::DAIKIN160; return decode_type_t::DAIKIN160;
else if (!strcasecmp(str, "DAIKIN176")) else if (!strcasecmp(str, "DAIKIN176"))
@ -264,6 +266,9 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) {
case DAIKIN: case DAIKIN:
result = F("DAIKIN"); result = F("DAIKIN");
break; break;
case DAIKIN128:
result = F("DAIKIN128");
break;
case DAIKIN160: case DAIKIN160:
result = F("DAIKIN160"); result = F("DAIKIN160");
break; break;
@ -464,6 +469,7 @@ bool hasACState(const decode_type_t protocol) {
switch (protocol) { switch (protocol) {
case ARGO: case ARGO:
case DAIKIN: case DAIKIN:
case DAIKIN128:
case DAIKIN160: case DAIKIN160:
case DAIKIN176: case DAIKIN176:
case DAIKIN2: case DAIKIN2:
@ -917,4 +923,30 @@ namespace irutils {
result += uint64ToString(mins % 60); result += uint64ToString(mins % 60);
return result; return result;
} }
// Sum all the nibbles together in a series of bytes.
// Args:
// start: PTR to the start of the bytes.
// length: Nr of bytes to sum the nibbles of.
// init: Starting value of the sum.
// Returns:
// A uint8_t sum of all the nibbles inc the init.
uint8_t sumNibbles(const uint8_t * const start, const uint16_t length,
const uint8_t init) {
uint8_t sum = init;
const uint8_t *ptr;
for (ptr = start; ptr - start < length; ptr++)
sum += (*ptr >> 4) + (*ptr & 0xF);
return sum;
}
uint8_t bcdToUint8(const uint8_t bcd) {
if (bcd > 0x99) return 255; // Too big.
return (bcd >> 4) * 10 + (bcd & 0xF);
}
uint8_t uint8ToBcd(const uint8_t integer) {
if (integer > 99) return 255; // Too big.
return ((integer / 10) << 4) + (integer % 10);
}
} // namespace irutils } // namespace irutils

View File

@ -56,5 +56,9 @@ namespace irutils {
String htmlEscape(const String unescaped); String htmlEscape(const String unescaped);
String msToString(uint32_t const msecs); String msToString(uint32_t const msecs);
String minsToString(const uint16_t mins); String minsToString(const uint16_t mins);
uint8_t sumNibbles(const uint8_t * const start, const uint16_t length,
const uint8_t init = 0);
uint8_t bcdToUint8(const uint8_t bcd);
uint8_t uint8ToBcd(const uint8_t integer);
} // namespace irutils } // namespace irutils
#endif // IRUTILS_H_ #endif // IRUTILS_H_

View File

@ -87,6 +87,7 @@ void IRsend::sendCOOLIX(uint64_t data, uint16_t nbits, uint16_t repeat) {
mark(kCoolixBitMark); mark(kCoolixBitMark);
space(kCoolixMinGap); // Pause before repeating space(kCoolixMinGap); // Pause before repeating
} }
space(kDefaultMessageGap);
} }
#endif #endif

View File

@ -34,7 +34,11 @@ using irutils::addLabeledString;
using irutils::addModeToString; using irutils::addModeToString;
using irutils::addTempToString; using irutils::addTempToString;
using irutils::addFanToString; using irutils::addFanToString;
using irutils::bcdToUint8;
using irutils::minsToString; using irutils::minsToString;
using irutils::sumNibbles;
using irutils::uint8ToBcd;
#if SEND_DAIKIN #if SEND_DAIKIN
// Send a Daikin A/C message. // Send a Daikin A/C message.
@ -2019,6 +2023,7 @@ bool IRrecv::decodeDaikin160(decode_results *results, const uint16_t nbits,
return true; return true;
} }
#endif // DECODE_DAIKIN160 #endif // DECODE_DAIKIN160
#if SEND_DAIKIN176 #if SEND_DAIKIN176
// Send a Daikin 176 bit A/C message. // Send a Daikin 176 bit A/C message.
// //
@ -2059,7 +2064,9 @@ void IRsend::sendDaikin176(const unsigned char data[], const uint16_t nbytes,
// //
// Supported Remotes: Daikin BRC4C153 remote // Supported Remotes: Daikin BRC4C153 remote
// //
IRDaikin176::IRDaikin176(uint16_t pin) : _irsend(pin) { stateReset(); } IRDaikin176::IRDaikin176(const uint16_t pin, const bool inverted,
const bool use_modulation)
: _irsend(pin, inverted, use_modulation) { stateReset(); }
void IRDaikin176::begin() { _irsend.begin(); } void IRDaikin176::begin() { _irsend.begin(); }
@ -2103,10 +2110,12 @@ void IRDaikin176::stateReset() {
remote_state[8] = 0xDA; remote_state[8] = 0xDA;
remote_state[9] = 0x17; remote_state[9] = 0x17;
remote_state[10] = 0x18; remote_state[10] = 0x18;
remote_state[12] = 0x03; remote_state[12] = 0x73;
remote_state[14] = 0x20; remote_state[14] = 0x20;
remote_state[18] = 0x16; // Fan speed and swing
remote_state[20] = 0x20; remote_state[20] = 0x20;
// remote_state[21] is a checksum byte, it will be set by checksum(). // remote_state[21] is a checksum byte, it will be set by checksum().
_saved_temp = getTemp();
} }
uint8_t *IRDaikin176::getRaw() { uint8_t *IRDaikin176::getRaw() {
@ -2117,6 +2126,7 @@ uint8_t *IRDaikin176::getRaw() {
void IRDaikin176::setRaw(const uint8_t new_code[]) { void IRDaikin176::setRaw(const uint8_t new_code[]) {
for (uint8_t i = 0; i < kDaikin176StateLength; i++) for (uint8_t i = 0; i < kDaikin176StateLength; i++)
remote_state[i] = new_code[i]; remote_state[i] = new_code[i];
_saved_temp = getTemp();
} }
#if SEND_DAIKIN176 #if SEND_DAIKIN176
@ -2126,19 +2136,16 @@ void IRDaikin176::send(const uint16_t repeat) {
} }
#endif // SEND_DAIKIN176 #endif // SEND_DAIKIN176
void IRDaikin176::on() { void IRDaikin176::on() { setPower(true); }
remote_state[kDaikin176BytePower] |= kDaikinBitPower;
}
void IRDaikin176::off() { void IRDaikin176::off() { setPower(false); }
remote_state[kDaikin176BytePower] &= ~kDaikinBitPower;
}
void IRDaikin176::setPower(const bool state) { void IRDaikin176::setPower(const bool state) {
remote_state[kDaikin176ByteModeButton] = 0;
if (state) if (state)
on(); remote_state[kDaikin176BytePower] |= kDaikinBitPower;
else else
off(); remote_state[kDaikin176BytePower] &= ~kDaikinBitPower;
} }
bool IRDaikin176::getPower() { bool IRDaikin176::getPower() {
@ -2150,42 +2157,60 @@ uint8_t IRDaikin176::getMode() {
} }
void IRDaikin176::setMode(const uint8_t mode) { void IRDaikin176::setMode(const uint8_t mode) {
uint8_t altmode = 0;
switch (mode) { switch (mode) {
case kDaikinAuto: case kDaikinFan: altmode = 0; break;
case kDaikin176Cool: case kDaikinDry: altmode = 7; break;
case kDaikinHeat: case kDaikin176Cool: altmode = 2; break;
case kDaikinFan: default: this->setMode(kDaikin176Cool); return;
case kDaikinDry:
remote_state[kDaikin176ByteMode] &= kDaikin176MaskMode;
remote_state[kDaikin176ByteMode] |= (mode << 4);
break;
default:
this->setMode(kDaikinAuto);
} }
// Set the mode.
remote_state[kDaikin176ByteMode] &= ~kDaikin176MaskMode;
remote_state[kDaikin176ByteMode] |= (mode << 4);
// Set the altmode
remote_state[kDaikin176BytePower] &= ~kDaikin176MaskMode;
remote_state[kDaikin176BytePower] |= (altmode << 4);
setTemp(_saved_temp);
// Needs to happen after setTemp() as it will clear it.
remote_state[kDaikin176ByteModeButton] = kDaikin176ModeButton;
} }
// Convert a standard A/C mode into its native mode. // Convert a standard A/C mode into its native mode.
uint8_t IRDaikin176::convertMode(const stdAc::opmode_t mode) { uint8_t IRDaikin176::convertMode(const stdAc::opmode_t mode) {
switch (mode) { switch (mode) {
case stdAc::opmode_t::kCool:
return kDaikin176Cool;
case stdAc::opmode_t::kHeat:
return kDaikinHeat;
case stdAc::opmode_t::kDry: case stdAc::opmode_t::kDry:
return kDaikinDry; return kDaikinDry;
case stdAc::opmode_t::kHeat: // Heat not supported, but fan is the closest.
case stdAc::opmode_t::kFan: case stdAc::opmode_t::kFan:
return kDaikinFan; return kDaikinFan;
default: default:
return kDaikinAuto; return kDaikin176Cool;
}
}
// Convert a native mode to it's common equivalent.
stdAc::opmode_t IRDaikin176::toCommonMode(const uint8_t mode) {
switch (mode) {
case kDaikinDry: return stdAc::opmode_t::kDry;
case kDaikinHeat: // There is no heat mode, but fan is the closest.
case kDaikinFan: return stdAc::opmode_t::kFan;
default: return stdAc::opmode_t::kCool;
} }
} }
// Set the temp in deg C // Set the temp in deg C
void IRDaikin176::setTemp(const uint8_t temp) { void IRDaikin176::setTemp(const uint8_t temp) {
uint8_t degrees = std::max(temp, kDaikinMinTemp); uint8_t degrees = std::min(kDaikinMaxTemp, std::max(temp, kDaikinMinTemp));
degrees = std::min(degrees, kDaikinMaxTemp) * 2 - 18; _saved_temp = degrees;
switch (getMode()) {
case kDaikinDry:
case kDaikinFan:
degrees = kDaikin176DryFanTemp;
}
degrees = degrees * 2 - 18;
remote_state[kDaikin176ByteTemp] &= ~kDaikin176MaskTemp; remote_state[kDaikin176ByteTemp] &= ~kDaikin176MaskTemp;
remote_state[kDaikin176ByteTemp] |= degrees; remote_state[kDaikin176ByteTemp] |= degrees;
remote_state[kDaikin176ByteModeButton] = 0;
} }
uint8_t IRDaikin176::getTemp(void) { uint8_t IRDaikin176::getTemp(void) {
@ -2194,45 +2219,43 @@ uint8_t IRDaikin176::getTemp(void) {
// Set the speed of the fan, 1 for Min or 3 for Max // Set the speed of the fan, 1 for Min or 3 for Max
void IRDaikin176::setFan(const uint8_t fan) { void IRDaikin176::setFan(const uint8_t fan) {
uint8_t fanset; switch (fan) {
if (fan == kDaikinFanQuiet || fan == kDaikinFanAuto) case kDaikinFanMin:
fanset = fan; case kDaikin176FanMax:
else if (fan < kDaikinFanMin || fan > kDaikinFanMax) remote_state[kDaikin176ByteFan] &= ~kDaikin176MaskFan;
fanset = kDaikinFanAuto; remote_state[kDaikin176ByteFan] |= (fan << 4);
else remote_state[kDaikin176ByteModeButton] = 0;
fanset = 2 + fan; break;
// Set the fan speed bits, leave *lower* 4 bits alone default:
remote_state[kDaikin176ByteFan] &= ~kDaikin176MaskFan; setFan(kDaikin176FanMax);
remote_state[kDaikin176ByteFan] |= (fanset << 4); }
} }
uint8_t IRDaikin176::getFan() { uint8_t IRDaikin176::getFan() { return remote_state[kDaikin176ByteFan] >> 4; }
uint8_t fan = remote_state[kDaikin176ByteFan] >> 4;
return fan;
}
// Convert a standard A/C Fan speed into its native fan speed. // Convert a standard A/C Fan speed into its native fan speed.
uint8_t IRDaikin176::convertFan(const stdAc::fanspeed_t speed) { uint8_t IRDaikin176::convertFan(const stdAc::fanspeed_t speed) {
switch (speed) { switch (speed) {
case stdAc::fanspeed_t::kMin: return kDaikinFanMin; case stdAc::fanspeed_t::kMin:
case stdAc::fanspeed_t::kLow: return kDaikinFanMin + 1; case stdAc::fanspeed_t::kLow:
case stdAc::fanspeed_t::kMedium: return kDaikinFanMin + 2; return kDaikinFanMin;
case stdAc::fanspeed_t::kHigh: return kDaikinFanMax - 1;
case stdAc::fanspeed_t::kMax: return kDaikinFanMax;
default: default:
return kDaikinFanAuto; return kDaikin176FanMax;
} }
} }
void IRDaikin176::setSwingHorizontal(const uint8_t position) { void IRDaikin176::setSwingHorizontal(const uint8_t position) {
switch (position) { switch (position) {
case kDaikin176SwingHSwing: case kDaikin176SwingHOff:
remote_state[kDaikin176ByteSwingH] &= kDaikin176MaskSwingH; case kDaikin176SwingHAuto:
remote_state[kDaikin176ByteSwingH] |= position; remote_state[kDaikin176ByteSwingH] &= ~kDaikin176MaskSwingH;
break; remote_state[kDaikin176ByteSwingH] |= position;
default: setSwingHorizontal(kDaikin176SwingHAuto); break;
default:
setSwingHorizontal(kDaikin176SwingHAuto);
} }
} }
uint8_t IRDaikin176::getSwingHorizontal() { uint8_t IRDaikin176::getSwingHorizontal() {
return remote_state[kDaikin176ByteSwingH] & kDaikin176MaskSwingH; return remote_state[kDaikin176ByteSwingH] & kDaikin176MaskSwingH;
} }
@ -2241,7 +2264,9 @@ uint8_t IRDaikin176::getSwingHorizontal() {
uint8_t IRDaikin176::convertSwingH(const stdAc::swingh_t position) { uint8_t IRDaikin176::convertSwingH(const stdAc::swingh_t position) {
switch (position) { switch (position) {
case stdAc::swingh_t::kOff: case stdAc::swingh_t::kOff:
return kDaikin176SwingHSwing; return kDaikin176SwingHOff;
case stdAc::swingh_t::kAuto:
return kDaikin176SwingHAuto;
default: default:
return kDaikin176SwingHAuto; return kDaikin176SwingHAuto;
} }
@ -2249,21 +2274,29 @@ uint8_t IRDaikin176::convertSwingH(const stdAc::swingh_t position) {
// Convert a native horizontal swing to it's common equivalent. // Convert a native horizontal swing to it's common equivalent.
stdAc::swingh_t IRDaikin176::toCommonSwingH(const uint8_t setting) { stdAc::swingh_t IRDaikin176::toCommonSwingH(const uint8_t setting) {
switch (setting) { switch (setting) {
case kDaikin176SwingHSwing: return stdAc::swingh_t::kOff; case kDaikin176SwingHOff: return stdAc::swingh_t::kOff;
default: return stdAc::swingh_t::kAuto; case kDaikin176SwingHAuto: return stdAc::swingh_t::kAuto;
default:
return stdAc::swingh_t::kAuto;
} }
} }
// Convert a native fan speed to it's common equivalent.
stdAc::fanspeed_t IRDaikin176::toCommonFanSpeed(const uint8_t speed) {
return (speed == kDaikinFanMin) ? stdAc::fanspeed_t::kMin
: stdAc::fanspeed_t::kMax;
}
// Convert the A/C state to it's common equivalent. // Convert the A/C state to it's common equivalent.
stdAc::state_t IRDaikin176::toCommon(void) { stdAc::state_t IRDaikin176::toCommon(void) {
stdAc::state_t result; stdAc::state_t result;
result.protocol = decode_type_t::DAIKIN176; result.protocol = decode_type_t::DAIKIN176;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = this->getPower(); result.power = this->getPower();
result.mode = IRDaikinESP::toCommonMode(this->getMode()); result.mode = IRDaikin176::toCommonMode(this->getMode());
result.celsius = true; result.celsius = true;
result.degrees = this->getTemp(); result.degrees = this->getTemp();
result.fanspeed = IRDaikinESP::toCommonFanSpeed(this->getFan()); result.fanspeed = this->toCommonFanSpeed(this->getFan());
result.swingh = this->toCommonSwingH(this->getSwingHorizontal()); result.swingh = this->toCommonSwingH(this->getSwingHorizontal());
// Not supported. // Not supported.
@ -2283,60 +2316,24 @@ stdAc::state_t IRDaikin176::toCommon(void) {
// Convert the internal state into a human readable string. // Convert the internal state into a human readable string.
String IRDaikin176::toString() { String IRDaikin176::toString() {
String result = ""; String result = "";
result.reserve(120); // Reserve some heap for the string to reduce fragging. result.reserve(80); // Reserve some heap for the string to reduce fragging.
result += F("Power: "); result += addBoolToString(getPower(), F("Power"), false);
if (this->getPower()) result += addModeToString(getMode(), kDaikinAuto, kDaikin176Cool, kDaikinHeat,
result += F("On"); kDaikinDry, kDaikinFan);
else result += addTempToString(getTemp());
result += F("Off"); result += addFanToString(getFan(), kDaikin176FanMax, kDaikinFanMin,
result += F(", Mode: "); kDaikinFanMin, kDaikinFanMin, kDaikinFanMin);
result += uint64ToString(this->getMode());
switch (getMode()) {
case kDaikinAuto:
result += F(" (AUTO)");
break;
case kDaikinCool + 4:
result += F(" (COOL)");
break;
case kDaikinHeat:
result += F(" (HEAT)");
break;
case kDaikinDry:
result += F(" (DRY)");
break;
case kDaikinFan:
result += F(" (FAN)");
break;
default:
result += F(" (UNKNOWN)");
}
result += F(", Temp: ");
result += uint64ToString(this->getTemp());
result += F("C, Fan: ");
result += uint64ToString(this->getFan());
switch (this->getFan()) {
case kDaikinFanAuto:
result += F(" (AUTO)");
break;
case kDaikinFanQuiet:
result += F(" (QUIET)");
break;
case kDaikinFanMin:
result += F(" (MIN)");
break;
case kDaikinFanMax - 2:
result += F(" (MAX)");
break;
}
result += F(", Swing (H): "); result += F(", Swing (H): ");
result += uint64ToString(getSwingHorizontal()); result += uint64ToString(getSwingHorizontal());
switch (getSwingHorizontal()) { switch (getSwingHorizontal()) {
case kDaikin176SwingHAuto: case kDaikin176SwingHAuto:
result += F(" (Auto)"); result += F(" (Auto)");
break; break;
case kDaikin176SwingHSwing: case kDaikin176SwingHOff:
result += F(" (Off)"); result += F(" (Off)");
break; break;
default:
result += F(" (UNKNOWN)");
} }
return result; return result;
} }
@ -2400,3 +2397,519 @@ bool IRrecv::decodeDaikin176(decode_results *results, const uint16_t nbits,
return true; return true;
} }
#endif // DECODE_DAIKIN176 #endif // DECODE_DAIKIN176
#if SEND_DAIKIN128
// Send a Daikin 128 bit A/C message.
//
// Args:
// data: An array of kDaikin128StateLength bytes containing the IR command.
//
// Status: STABLE / Known Working.
//
// Supported devices:
// - Daikin BRC52B63 remote.
//
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827
void IRsend::sendDaikin128(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) {
if (nbytes < kDaikin128SectionLength)
return; // Not enough bytes to send a partial message.
for (uint16_t r = 0; r <= repeat; r++) {
enableIROut(kDaikin128Freq);
// Leader
for (uint8_t i = 0; i < 2; i++) {
mark(kDaikin128LeaderMark);
space(kDaikin128LeaderSpace);
}
// Section #1 (Header + Data)
sendGeneric(kDaikin128HdrMark, kDaikin128HdrSpace, kDaikin128BitMark,
kDaikin128OneSpace, kDaikin128BitMark, kDaikin128ZeroSpace,
kDaikin128BitMark, kDaikin128Gap, data,
kDaikin128SectionLength,
kDaikin128Freq, false, 0, kDutyDefault);
// Section #2 (Data + Footer)
sendGeneric(0, 0, kDaikin128BitMark,
kDaikin128OneSpace, kDaikin128BitMark, kDaikin128ZeroSpace,
kDaikin128FooterMark, kDaikin128Gap,
data + kDaikin128SectionLength,
nbytes - kDaikin128SectionLength,
kDaikin128Freq, false, 0, kDutyDefault);
}
}
#endif // SEND_DAIKIN128
// Class for handling Daikin 128 bit / 16 byte A/C messages.
//
// Code by crankyoldgit.
// Analysis by Daniel Vena
//
// Status: STABLE / Known Working.
//
// Supported Remotes: Daikin BRC52B63 remote
//
IRDaikin128::IRDaikin128(const uint16_t pin, const bool inverted,
const bool use_modulation)
: _irsend(pin, inverted, use_modulation) { stateReset(); }
void IRDaikin128::begin() { _irsend.begin(); }
uint8_t IRDaikin128::calcFirstChecksum(const uint8_t state[]) {
return sumNibbles(state, kDaikin128SectionLength - 1,
state[kDaikin128SectionLength - 1] & 0x0F) & 0x0F;
}
uint8_t IRDaikin128::calcSecondChecksum(const uint8_t state[]) {
return sumNibbles(state + kDaikin128SectionLength,
kDaikin128SectionLength - 1);
}
// Verify the checksum is valid for a given state.
// Args:
// state: The array to verify the checksum of.
// Returns:
// A boolean.
bool IRDaikin128::validChecksum(uint8_t state[]) {
// Validate the checksum of section #1.
if (state[kDaikin128SectionLength - 1] >> 4 != calcFirstChecksum(state))
return false;
// Validate the checksum of section #2
if (state[kDaikin128StateLength - 1] != calcSecondChecksum(state))
return false;
return true;
}
// Calculate and set the checksum values for the internal state.
void IRDaikin128::checksum() {
remote_state[kDaikin128SectionLength - 1] &= 0x0F; // Clear upper half.
remote_state[kDaikin128SectionLength - 1] |=
(calcFirstChecksum(remote_state) << 4);
remote_state[kDaikin128StateLength - 1] = calcSecondChecksum(remote_state);
}
void IRDaikin128::stateReset() {
for (uint8_t i = 0; i < kDaikin128StateLength; i++) remote_state[i] = 0x00;
remote_state[0] = 0x16;
remote_state[7] = 0x04; // Most significant nibble is a checksum.
remote_state[8] = 0xA1;
// remote_state[15] is a checksum byte, it will be set by checksum().
}
uint8_t *IRDaikin128::getRaw() {
checksum(); // Ensure correct settings before sending.
return remote_state;
}
void IRDaikin128::setRaw(const uint8_t new_code[]) {
for (uint8_t i = 0; i < kDaikin128StateLength; i++)
remote_state[i] = new_code[i];
}
#if SEND_DAIKIN128
void IRDaikin128::send(const uint16_t repeat) {
checksum();
_irsend.sendDaikin128(remote_state, kDaikin128StateLength, repeat);
}
#endif // SEND_DAIKIN128
void IRDaikin128::setPowerToggle(const bool toggle) {
if (toggle)
remote_state[kDaikin128BytePowerSwingSleep] |= kDaikin128BitPowerToggle;
else
remote_state[kDaikin128BytePowerSwingSleep] &= ~kDaikin128BitPowerToggle;
}
bool IRDaikin128::getPowerToggle(void) {
return remote_state[kDaikin128BytePowerSwingSleep] & kDaikin128BitPowerToggle;
}
uint8_t IRDaikin128::getMode() {
return remote_state[kDaikin128ByteModeFan] & kDaikin128MaskMode;
}
void IRDaikin128::setMode(const uint8_t mode) {
switch (mode) {
case kDaikin128Auto:
case kDaikin128Cool:
case kDaikin128Heat:
case kDaikin128Fan:
case kDaikin128Dry:
remote_state[kDaikin128ByteModeFan] &= ~kDaikin128MaskMode;
remote_state[kDaikin128ByteModeFan] |= mode;
break;
default:
this->setMode(kDaikin128Auto);
return;
}
// Force a reset of mode dependant things.
setFan(getFan()); // Covers Quiet & Powerful too.
setEcono(getEcono());
}
// Convert a standard A/C mode into its native mode.
uint8_t IRDaikin128::convertMode(const stdAc::opmode_t mode) {
switch (mode) {
case stdAc::opmode_t::kCool:
return kDaikin128Cool;
case stdAc::opmode_t::kHeat:
return kDaikin128Heat;
case stdAc::opmode_t::kDry:
return kDaikinDry;
case stdAc::opmode_t::kFan:
return kDaikin128Fan;
default:
return kDaikin128Auto;
}
}
// Convert a native mode to it's common equivalent.
stdAc::opmode_t IRDaikin128::toCommonMode(const uint8_t mode) {
switch (mode) {
case kDaikin128Cool: return stdAc::opmode_t::kCool;
case kDaikin128Heat: return stdAc::opmode_t::kHeat;
case kDaikin128Dry: return stdAc::opmode_t::kDry;
case kDaikin128Fan: return stdAc::opmode_t::kFan;
default: return stdAc::opmode_t::kAuto;
}
}
// Set the temp in deg C
void IRDaikin128::setTemp(const uint8_t temp) {
remote_state[kDaikin128ByteTemp] = uint8ToBcd(
std::min(kDaikin128MaxTemp, std::max(temp, kDaikin128MinTemp)));
}
uint8_t IRDaikin128::getTemp(void) {
return bcdToUint8(remote_state[kDaikin128ByteTemp]);
}
uint8_t IRDaikin128::getFan() {
return (remote_state[kDaikin128ByteModeFan] & kDaikin128MaskFan) >> 4;
}
void IRDaikin128::setFan(const uint8_t speed) {
uint8_t new_speed = speed;
uint8_t mode = getMode();
switch (speed) {
case kDaikin128FanQuiet:
case kDaikin128FanPowerful:
if (mode == kDaikin128Auto) new_speed = kDaikin128FanAuto;
// FALL-THRU
case kDaikin128FanAuto:
case kDaikin128FanHigh:
case kDaikin128FanMed:
case kDaikin128FanLow:
// if (mode == kDaikinDry) new_speed = kDaikin128FanMed;
remote_state[kDaikin128ByteModeFan] &= ~kDaikin128MaskFan;
remote_state[kDaikin128ByteModeFan] |= (new_speed << 4);
break;
default:
this->setFan(kDaikin128FanAuto);
}
}
// Convert a standard A/C Fan speed into its native fan speed.
uint8_t IRDaikin128::convertFan(const stdAc::fanspeed_t speed) {
switch (speed) {
case stdAc::fanspeed_t::kMin: return kDaikinFanQuiet;
case stdAc::fanspeed_t::kLow: return kDaikin128FanLow;
case stdAc::fanspeed_t::kMedium: return kDaikin128FanMed;
case stdAc::fanspeed_t::kHigh: return kDaikin128FanHigh;
case stdAc::fanspeed_t::kMax: return kDaikin128FanPowerful;
default: return kDaikin128FanAuto;
}
}
// Convert a native fan speed to it's common equivalent.
stdAc::fanspeed_t IRDaikin128::toCommonFanSpeed(const uint8_t speed) {
switch (speed) {
case kDaikin128FanPowerful: return stdAc::fanspeed_t::kMax;
case kDaikin128FanHigh: return stdAc::fanspeed_t::kHigh;
case kDaikin128FanMed: return stdAc::fanspeed_t::kMedium;
case kDaikin128FanLow: return stdAc::fanspeed_t::kLow;
case kDaikinFanQuiet: return stdAc::fanspeed_t::kMin;
default: return stdAc::fanspeed_t::kAuto;
}
}
void IRDaikin128::setSwingVertical(const bool on) {
if (on)
remote_state[kDaikin128BytePowerSwingSleep] |= kDaikin128BitSwing;
else
remote_state[kDaikin128BytePowerSwingSleep] &= ~kDaikin128BitSwing;
}
bool IRDaikin128::getSwingVertical(void) {
return remote_state[kDaikin128BytePowerSwingSleep] & kDaikin128BitSwing;
}
void IRDaikin128::setSleep(const bool on) {
if (on)
remote_state[kDaikin128BytePowerSwingSleep] |= kDaikin128BitSleep;
else
remote_state[kDaikin128BytePowerSwingSleep] &= ~kDaikin128BitSleep;
}
bool IRDaikin128::getSleep(void) {
return remote_state[kDaikin128BytePowerSwingSleep] & kDaikin128BitSleep;
}
void IRDaikin128::setEcono(const bool on) {
uint8_t mode = getMode();
if (on && (mode == kDaikin128Cool || mode == kDaikin128Heat))
remote_state[kDaikin128ByteEconoLight] |= kDaikin128BitEcono;
else
remote_state[kDaikin128ByteEconoLight] &= ~kDaikin128BitEcono;
}
bool IRDaikin128::getEcono(void) {
return remote_state[kDaikin128ByteEconoLight] & kDaikin128BitEcono;
}
void IRDaikin128::setQuiet(const bool on) {
uint8_t mode = getMode();
if (on && (mode == kDaikin128Cool || mode == kDaikin128Heat))
setFan(kDaikin128FanQuiet);
else if (getFan() == kDaikin128FanQuiet)
setFan(kDaikin128FanAuto);
}
bool IRDaikin128::getQuiet(void) {
return getFan() == kDaikin128FanQuiet;
}
void IRDaikin128::setPowerful(const bool on) {
uint8_t mode = getMode();
if (on && (mode == kDaikin128Cool || mode == kDaikin128Heat))
setFan(kDaikin128FanPowerful);
else if (getFan() == kDaikin128FanPowerful)
setFan(kDaikin128FanAuto);
}
bool IRDaikin128::getPowerful(void) {
return getFan() == kDaikin128FanPowerful;
}
// Set the clock in mins since midnight
void IRDaikin128::setClock(const uint16_t mins_since_midnight) {
uint16_t mins = mins_since_midnight;
if (mins_since_midnight >= 24 * 60) mins = 0; // Bounds check.
// Hours.
remote_state[kDaikin128ByteClockHours] = uint8ToBcd(mins / 60);
// Minutes.
remote_state[kDaikin128ByteClockMins] = uint8ToBcd(mins % 60);
}
uint16_t IRDaikin128::getClock(void) {
return bcdToUint8(remote_state[kDaikin128ByteClockHours]) * 60 +
bcdToUint8(remote_state[kDaikin128ByteClockMins]);
}
void IRDaikin128::setOnTimerEnabled(const bool on) {
if (on)
remote_state[kDaikin128ByteOnTimer] |= kDaikin128BitTimerEnabled;
else
remote_state[kDaikin128ByteOnTimer] &= ~kDaikin128BitTimerEnabled;
}
bool IRDaikin128::getOnTimerEnabled(void) {
return remote_state[kDaikin128ByteOnTimer] & kDaikin128BitTimerEnabled;
}
// Timer is rounds down to the nearest half hour.
// Args:
// ptr: A PTR to the byte containing the Timer value to be updated.
// mins_since_midnight: The number of minutes the new timer should be set to.
void IRDaikin128::setTimer(uint8_t *ptr, const uint16_t mins_since_midnight) {
uint16_t mins = mins_since_midnight;
if (mins_since_midnight >= 24 * 60) mins = 0; // Bounds check.
// Clear the time component
*ptr &= kDaikin128BitTimerEnabled;
uint8_t bcdhours = uint8ToBcd(mins / 60);
bool addhalf = (mins % 60) >= 30;
*ptr |= ((addhalf << 6) | bcdhours);
}
// Timer is stored in nr of half hours internally.
// Args:
// ptr: A PTR to the byte containing the Timer value.
// Returns:
// A uint16_t containing the number of minutes since midnight.
uint16_t IRDaikin128::getTimer(const uint8_t *ptr) {
uint8_t bcdhours = *ptr & kDaikin128MaskHours;
bool addhalf = *ptr & kDaikin128BitHalfHour;
return bcdToUint8(bcdhours) * 60 + (addhalf ? 30 : 0);
}
void IRDaikin128::setOnTimer(const uint16_t mins_since_midnight) {
setTimer(remote_state + kDaikin128ByteOnTimer, mins_since_midnight);
}
uint16_t IRDaikin128::getOnTimer(void) {
return getTimer(remote_state + kDaikin128ByteOnTimer);
}
void IRDaikin128::setOffTimerEnabled(const bool on) {
if (on)
remote_state[kDaikin128ByteOffTimer] |= kDaikin128BitTimerEnabled;
else
remote_state[kDaikin128ByteOffTimer] &= ~kDaikin128BitTimerEnabled;
}
bool IRDaikin128::getOffTimerEnabled(void) {
return remote_state[kDaikin128ByteOffTimer] & kDaikin128BitTimerEnabled;
}
void IRDaikin128::setOffTimer(const uint16_t mins_since_midnight) {
setTimer(remote_state + kDaikin128ByteOffTimer, mins_since_midnight);
}
uint16_t IRDaikin128::getOffTimer(void) {
return getTimer(remote_state + kDaikin128ByteOffTimer);
}
void IRDaikin128::setLightToggle(const uint8_t unit) {
switch (unit) {
case kDaikin128BitCeiling:
case kDaikin128BitWall:
case 0:
remote_state[kDaikin128ByteEconoLight] &= ~kDaikin128MaskLight;
remote_state[kDaikin128ByteEconoLight] |= unit;
break;
default: setLightToggle(0);
}
}
uint8_t IRDaikin128::getLightToggle(void) {
return remote_state[kDaikin128ByteEconoLight] & kDaikin128MaskLight;
}
// Convert the internal state into a human readable string.
String IRDaikin128::toString(void) {
String result = "";
result.reserve(240); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPowerToggle(), F("Power Toggle"), false);
result += addModeToString(getMode(), kDaikin128Auto, kDaikin128Cool,
kDaikin128Heat, kDaikin128Dry, kDaikin128Fan);
result += addTempToString(getTemp());
result += addFanToString(getFan(), kDaikin128FanHigh, kDaikin128FanLow,
kDaikin128FanAuto, kDaikin128FanQuiet,
kDaikin128FanMed);
result += addBoolToString(getPowerful(), F("Powerful"));
result += addBoolToString(getQuiet(), F("Quiet"));
result += addBoolToString(getSwingVertical(), F("Swing (V)"));
result += addBoolToString(getSleep(), F("Sleep"));
result += addBoolToString(getEcono(), F("Econo"));
result += addLabeledString(minsToString(getClock()), F("Clock"));
result += addBoolToString(getOnTimerEnabled(), F("On Timer"));
result += addLabeledString(minsToString(getOnTimer()), F("On Time"));
result += addBoolToString(getOffTimerEnabled(), F("Off Timer"));
result += addLabeledString(minsToString(getOffTimer()), F("Off Time"));
result += addIntToString(getLightToggle(), F("Light Toggle"));
result += F(" (");
switch (getLightToggle()) {
case kDaikin128BitCeiling: result += F("Ceiling"); break;
case kDaikin128BitWall: result += F("Wall"); break;
case 0: result += F("Off"); break;
default: result += F("UNKNOWN");
}
result += ')';
return result;
}
// Convert the A/C state to it's common equivalent.
stdAc::state_t IRDaikin128::toCommon(const stdAc::state_t *prev) {
stdAc::state_t result;
if (prev != NULL) result = *prev;
result.protocol = decode_type_t::DAIKIN128;
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.quiet = getQuiet();
result.turbo = getPowerful();
result.econo = getEcono();
result.light ^= (getLightToggle() != 0);
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;
return result;
}
#if DECODE_DAIKIN128
// Decode the supplied Daikin 128 bit A/C message.
// Args:
// results: Ptr to the data to decode and where to store the decode result.
// nbits: Nr. of bits to expect in the data portion. (kDaikin128Bits)
// 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 BRC52B63 remote.
//
// Status: STABLE / Known Working.
//
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827
bool IRrecv::decodeDaikin128(decode_results *results, const uint16_t nbits,
const bool strict) {
if (results->rawlen < 2 * (nbits + kHeader) + kFooter - 1)
return false;
if (nbits / 8 <= kDaikin128SectionLength) return false;
// Compliance
if (strict && nbits != kDaikin128Bits) return false;
uint16_t offset = kStartOffset;
// Leader
for (uint8_t i = 0; i < 2; i++) {
if (!matchMark(results->rawbuf[offset++], kDaikin128LeaderMark,
kDaikinTolerance, kDaikinMarkExcess)) return false;
if (!matchSpace(results->rawbuf[offset++], kDaikin128LeaderSpace,
kDaikinTolerance, kDaikinMarkExcess)) return false;
}
const uint16_t ksectionSize[kDaikin128Sections] = {
kDaikin128SectionLength, (uint16_t)(nbits / 8 - kDaikin128SectionLength)};
// Data Sections
uint16_t pos = 0;
for (uint8_t section = 0; section < kDaikin128Sections; section++) {
uint16_t used;
// Section Header (first section only) + Section Data (8 bytes) +
// Section Footer (Not for first section)
used = matchGeneric(results->rawbuf + offset, results->state + pos,
results->rawlen - offset, ksectionSize[section] * 8,
section == 0 ? kDaikin128HdrMark : 0,
section == 0 ? kDaikin128HdrSpace : 0,
kDaikin128BitMark, kDaikin128OneSpace,
kDaikin128BitMark, kDaikin128ZeroSpace,
section > 0 ? kDaikin128FooterMark : kDaikin128BitMark,
kDaikin128Gap,
section > 0,
kDaikinTolerance, kDaikinMarkExcess, false);
if (used == 0) return false;
offset += used;
pos += ksectionSize[section];
}
// Compliance
if (strict) {
if (!IRDaikin128::validChecksum(results->state)) return false;
}
// Success
results->decode_type = decode_type_t::DAIKIN128;
results->bits = nbits;
// No need to record the state as we stored it as we decoded it.
// As we use result->state, we don't record value, address, or command as it
// is a union data type.
return true;
}
#endif // DECODE_DAIKIN128

View File

@ -11,6 +11,12 @@
// Brand: Daikin, Model: ARC433B69 remote // Brand: Daikin, Model: ARC433B69 remote
// Brand: Daikin, Model: ARC423A5 remote // Brand: Daikin, Model: ARC423A5 remote
// Brand: Daikin, Model: FTE12HV2S A/C // Brand: Daikin, Model: FTE12HV2S A/C
// Brand: Daikin, Model: BRC4C153 remote
// Brand: Daikin, Model: 17 Series A/C (DAIKIN128)
// Brand: Daikin, Model: FTXB12AXVJU A/C (DAIKIN128)
// Brand: Daikin, Model: FTXB09AXVJU A/C (DAIKIN128)
// Brand: Daikin, Model: BRC52B63 remote (DAIKIN128)
#ifndef IR_DAIKIN_H_ #ifndef IR_DAIKIN_H_
#define IR_DAIKIN_H_ #define IR_DAIKIN_H_
@ -257,18 +263,70 @@ const uint16_t kDaikin176Sections = 2;
const uint16_t kDaikin176Section1Length = 7; const uint16_t kDaikin176Section1Length = 7;
const uint16_t kDaikin176Section2Length = kDaikin176StateLength - const uint16_t kDaikin176Section2Length = kDaikin176StateLength -
kDaikin176Section1Length; kDaikin176Section1Length;
const uint8_t kDaikin176Cool = 0b111; const uint8_t kDaikin176Cool = 0b111; // 7
const uint8_t kDaikin176BytePower = 14; const uint8_t kDaikin176BytePower = 14;
const uint8_t kDaikin176ByteMode = 12; const uint8_t kDaikin176ByteMode = 12;
const uint8_t kDaikin176MaskMode = 0b01110011; const uint8_t kDaikin176MaskMode = 0b01110000;
const uint8_t kDaikin176ByteModeButton = 13;
const uint8_t kDaikin176ModeButton = 0b00000100;
const uint8_t kDaikin176ByteTemp = 17; const uint8_t kDaikin176ByteTemp = 17;
const uint8_t kDaikin176MaskTemp = 0b01111110; const uint8_t kDaikin176MaskTemp = 0b01111110;
const uint8_t kDaikin176DryFanTemp = 17; // Dry/Fan mode is always 17 Celsius.
const uint8_t kDaikin176ByteFan = 18; const uint8_t kDaikin176ByteFan = 18;
const uint8_t kDaikin176MaskFan = 0b11110000; const uint8_t kDaikin176MaskFan = 0b11110000;
const uint8_t kDaikin176FanMax = 3;
const uint8_t kDaikin176ByteSwingH = 18; const uint8_t kDaikin176ByteSwingH = 18;
const uint8_t kDaikin176MaskSwingH = 0b00001111; const uint8_t kDaikin176MaskSwingH = 0b00001111;
const uint8_t kDaikin176SwingHAuto = 0x5; const uint8_t kDaikin176SwingHAuto = 0x5;
const uint8_t kDaikin176SwingHSwing = 0x6; const uint8_t kDaikin176SwingHOff = 0x6;
// Another variant of the protocol for the Daikin BRC52B63 remote.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/827
const uint16_t kDaikin128Freq = 38000; // Modulation Frequency in Hz.
const uint16_t kDaikin128LeaderMark = 9800;
const uint16_t kDaikin128LeaderSpace = 9800;
const uint16_t kDaikin128HdrMark = 4600;
const uint16_t kDaikin128HdrSpace = 2500;
const uint16_t kDaikin128BitMark = 350;
const uint16_t kDaikin128OneSpace = 954;
const uint16_t kDaikin128ZeroSpace = 382;
const uint16_t kDaikin128Gap = 20300;
const uint16_t kDaikin128FooterMark = kDaikin128HdrMark;
const uint16_t kDaikin128Sections = 2;
const uint16_t kDaikin128SectionLength = 8;
const uint8_t kDaikin128ByteModeFan = 1;
const uint8_t kDaikin128MaskMode = 0b00001111;
const uint8_t kDaikin128Dry = 0b00000001;
const uint8_t kDaikin128Cool = 0b00000010;
const uint8_t kDaikin128Fan = 0b00000100;
const uint8_t kDaikin128Heat = 0b00001000;
const uint8_t kDaikin128Auto = 0b00001010;
const uint8_t kDaikin128MaskFan = 0b11110000;
const uint8_t kDaikin128FanAuto = 0b0001;
const uint8_t kDaikin128FanHigh = 0b0010;
const uint8_t kDaikin128FanMed = 0b0100;
const uint8_t kDaikin128FanLow = 0b1000;
const uint8_t kDaikin128FanPowerful = 0b0011;
const uint8_t kDaikin128FanQuiet = 0b1001;
const uint8_t kDaikin128ByteClockMins = 2;
const uint8_t kDaikin128ByteClockHours = 3;
const uint8_t kDaikin128ByteOnTimer = 4;
const uint8_t kDaikin128ByteOffTimer = 5;
const uint8_t kDaikin128BitTimerEnabled = 0b10000000;
const uint8_t kDaikin128BitHalfHour = 0b01000000;
const uint8_t kDaikin128MaskHours = 0b00111111;
const uint8_t kDaikin128ByteTemp = 6;
const uint8_t kDaikin128MinTemp = 16; // C
const uint8_t kDaikin128MaxTemp = 30; // C
const uint8_t kDaikin128BytePowerSwingSleep = 7;
const uint8_t kDaikin128BitSwing = 0b00000001;
const uint8_t kDaikin128BitSleep = 0b00000010;
const uint8_t kDaikin128BitPowerToggle = 0b00001000;
const uint8_t kDaikin128ByteEconoLight = 9;
const uint8_t kDaikin128BitEcono = 0b00000100;
const uint8_t kDaikin128BitWall = 0b00001000;
const uint8_t kDaikin128BitCeiling = 0b00000001;
const uint8_t kDaikin128MaskLight = kDaikin128BitWall | kDaikin128BitCeiling;
// Legacy defines. // Legacy defines.
#define DAIKIN_COOL kDaikinCool #define DAIKIN_COOL kDaikinCool
@ -548,7 +606,8 @@ class IRDaikin160 {
// Class to emulate a Daikin BRC4C153 remote. // Class to emulate a Daikin BRC4C153 remote.
class IRDaikin176 { class IRDaikin176 {
public: public:
explicit IRDaikin176(uint16_t pin); explicit IRDaikin176(const uint16_t pin, const bool inverted = false,
const bool use_modulation = true);
#if SEND_DAIKIN176 #if SEND_DAIKIN176
void send(const uint16_t repeat = kDaikin176DefaultRepeat); void send(const uint16_t repeat = kDaikin176DefaultRepeat);
@ -572,8 +631,10 @@ class IRDaikin176 {
uint8_t getFan(void); uint8_t getFan(void);
static uint8_t convertFan(const stdAc::fanspeed_t speed); static uint8_t convertFan(const stdAc::fanspeed_t speed);
void setSwingHorizontal(const uint8_t position); void setSwingHorizontal(const uint8_t position);
uint8_t getSwingHorizontal(); uint8_t getSwingHorizontal(void);
static uint8_t convertSwingH(const stdAc::swingh_t position); static uint8_t convertSwingH(const stdAc::swingh_t position);
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
static stdAc::opmode_t toCommonMode(const uint8_t mode);
static stdAc::swingh_t toCommonSwingH(const uint8_t setting); static stdAc::swingh_t toCommonSwingH(const uint8_t setting);
stdAc::state_t toCommon(void); stdAc::state_t toCommon(void);
String toString(void); String toString(void);
@ -587,8 +648,77 @@ class IRDaikin176 {
#endif #endif
// # of bytes per command // # of bytes per command
uint8_t remote_state[kDaikin176StateLength]; uint8_t remote_state[kDaikin176StateLength];
uint8_t _saved_temp;
void stateReset(); void stateReset();
void checksum(); void checksum();
}; };
// Class to emulate a Daikin BRC52B63 remote / Daikin 17 series A/C.
class IRDaikin128 {
public:
explicit IRDaikin128(const uint16_t pin, const bool inverted = false,
const bool use_modulation = true);
#if SEND_DAIKIN128
void send(const uint16_t repeat = kDaikin128DefaultRepeat);
uint8_t calibrate(void) { return _irsend.calibrate(); }
#endif // SEND_DAIKIN128
void begin();
void setPowerToggle(const bool toggle);
bool getPowerToggle(void);
void setTemp(const uint8_t temp);
uint8_t getTemp(void);
void setFan(const uint8_t fan);
uint8_t getFan(void);
uint8_t getMode(void);
void setMode(const uint8_t mode);
void setSwingVertical(const bool on);
bool getSwingVertical();
bool getSleep(void);
void setSleep(const bool on);
bool getQuiet(void);
void setQuiet(const bool on);
bool getPowerful(void);
void setPowerful(const bool on);
void setEcono(const bool on);
bool getEcono(void);
void setOnTimer(const uint16_t mins_since_midnight);
uint16_t getOnTimer(void);
bool getOnTimerEnabled(void);
void setOnTimerEnabled(const bool on);
void setOffTimer(const uint16_t mins_since_midnight);
uint16_t getOffTimer(void);
bool getOffTimerEnabled(void);
void setOffTimerEnabled(const bool on);
void setClock(const uint16_t mins_since_midnight);
uint16_t getClock(void);
void setLightToggle(const uint8_t unit_type);
uint8_t getLightToggle(void);
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[]);
static bool validChecksum(uint8_t state[]);
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
// # of bytes per command
uint8_t remote_state[kDaikin128StateLength];
void stateReset(void);
static uint8_t calcFirstChecksum(const uint8_t state[]);
static uint8_t calcSecondChecksum(const uint8_t state[]);
static void setTimer(uint8_t *ptr, const uint16_t mins_since_midnight);
static uint16_t getTimer(const uint8_t *ptr);
void checksum(void);
void clearOnTimerFlag(void);
void clearSleepTimerFlag(void);
};
#endif // IR_DAIKIN_H_ #endif // IR_DAIKIN_H_

View File

@ -113,9 +113,12 @@ void IRsend::sendGree(const uint64_t data, const uint16_t nbits,
} }
#endif // SEND_GREE #endif // SEND_GREE
IRGreeAC::IRGreeAC(const uint16_t pin, const bool inverted, IRGreeAC::IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model,
const bool use_modulation) const bool inverted, const bool use_modulation)
: _irsend(pin, inverted, use_modulation) { stateReset(); } : _irsend(pin, inverted, use_modulation) {
stateReset();
setModel(model);
}
void IRGreeAC::stateReset(void) { void IRGreeAC::stateReset(void) {
// This resets to a known-good state to Power Off, Fan Auto, Mode Auto, 25C. // This resets to a known-good state to Power Off, Fan Auto, Mode Auto, 25C.
@ -128,6 +131,7 @@ void IRGreeAC::stateReset(void) {
} }
void IRGreeAC::fixup(void) { void IRGreeAC::fixup(void) {
setPower(getPower()); // Redo the power bits as they differ between models.
checksum(); // Calculate the checksums checksum(); // Calculate the checksums
} }
@ -149,6 +153,13 @@ void IRGreeAC::setRaw(const uint8_t new_code[]) {
for (uint8_t i = 0; i < kGreeStateLength; i++) { for (uint8_t i = 0; i < kGreeStateLength; i++) {
remote_state[i] = new_code[i]; remote_state[i] = new_code[i];
} }
// We can only detect the difference between models when the power is on.
if (getPower()) {
if (remote_state[2] & kGreePower2Mask)
_model = gree_ac_remote_model_t::YAW1F;
else
_model = gree_ac_remote_model_t::YBOFB;
}
} }
void IRGreeAC::checksum(const uint16_t length) { void IRGreeAC::checksum(const uint16_t length) {
@ -165,33 +176,45 @@ void IRGreeAC::checksum(const uint16_t length) {
// A boolean. // A boolean.
bool IRGreeAC::validChecksum(const uint8_t state[], const uint16_t length) { bool IRGreeAC::validChecksum(const uint8_t state[], const uint16_t length) {
// Top 4 bits of the last byte in the state is the state's checksum. // Top 4 bits of the last byte in the state is the state's checksum.
if (state[length - 1] >> 4 == return (state[length - 1] >> 4 == IRKelvinatorAC::calcBlockChecksum(state,
IRKelvinatorAC::calcBlockChecksum(state, length)) length));
return true;
else
return false;
} }
void IRGreeAC::on(void) { void IRGreeAC::setModel(const gree_ac_remote_model_t model) {
remote_state[0] |= kGreePower1Mask; switch (model) {
remote_state[2] |= kGreePower2Mask; case gree_ac_remote_model_t::YAW1F:
case gree_ac_remote_model_t::YBOFB:
_model = model; break;
default:
setModel(gree_ac_remote_model_t::YAW1F);
}
} }
void IRGreeAC::off(void) { gree_ac_remote_model_t IRGreeAC::getModel(void) {
remote_state[0] &= ~kGreePower1Mask; return _model;
remote_state[2] &= ~kGreePower2Mask;
} }
void IRGreeAC::on(void) { setPower(true); }
void IRGreeAC::off(void) { setPower(false); }
void IRGreeAC::setPower(const bool on) { void IRGreeAC::setPower(const bool on) {
if (on) if (on) {
this->on(); remote_state[0] |= kGreePower1Mask;
else switch (_model) {
this->off(); case gree_ac_remote_model_t::YBOFB: break;
default:
remote_state[2] |= kGreePower2Mask;
}
} else {
remote_state[0] &= ~kGreePower1Mask;
remote_state[2] &= ~kGreePower2Mask; // May not be needed. See #814
}
} }
bool IRGreeAC::getPower(void) { bool IRGreeAC::getPower(void) {
return (remote_state[0] & kGreePower1Mask) && // See #814. Not checking/requiring: (remote_state[2] & kGreePower2Mask)
(remote_state[2] & kGreePower2Mask); return remote_state[0] & kGreePower1Mask;
} }
// Set the temp. in deg C // Set the temp. in deg C
@ -424,7 +447,7 @@ stdAc::swingv_t IRGreeAC::toCommonSwingV(const uint8_t pos) {
stdAc::state_t IRGreeAC::toCommon(void) { stdAc::state_t IRGreeAC::toCommon(void) {
stdAc::state_t result; stdAc::state_t result;
result.protocol = decode_type_t::GREE; result.protocol = decode_type_t::GREE;
result.model = -1; // No models used. result.model = this->getModel();
result.power = this->getPower(); result.power = this->getPower();
result.mode = this->toCommonMode(this->getMode()); result.mode = this->toCommonMode(this->getMode());
result.celsius = true; result.celsius = true;
@ -452,7 +475,13 @@ stdAc::state_t IRGreeAC::toCommon(void) {
String IRGreeAC::toString(void) { String IRGreeAC::toString(void) {
String result = ""; String result = "";
result.reserve(150); // Reserve some heap for the string to reduce fragging. result.reserve(150); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), F("Power"), false); result += addIntToString(getModel(), F("Model"), false);
switch (getModel()) {
case gree_ac_remote_model_t::YAW1F: result += F(" (YAW1F)"); break;
case gree_ac_remote_model_t::YBOFB: result += F(" (YBOFB)"); break;
default: result += F(" (UNKNOWN)");
}
result += addBoolToString(getPower(), F("Power"));
result += addModeToString(getMode(), kGreeAuto, kGreeCool, kGreeHeat, result += addModeToString(getMode(), kGreeAuto, kGreeCool, kGreeHeat,
kGreeDry, kGreeFan); kGreeDry, kGreeFan);
result += addTempToString(getTemp()); result += addTempToString(getTemp());

View File

@ -6,6 +6,8 @@
// Brand: EKOKAI, Model: A/C // Brand: EKOKAI, Model: A/C
// Brand: RusClimate, Model: EACS/I-09HAR_X/N3 A/C // Brand: RusClimate, Model: EACS/I-09HAR_X/N3 A/C
// Brand: RusClimate, Model: YAW1F remote // Brand: RusClimate, Model: YAW1F remote
// Brand: Green, Model: YBOFB remote
// Brand: Green, Model: YBOFB2 remote
#ifndef IR_GREE_H_ #ifndef IR_GREE_H_
#define IR_GREE_H_ #define IR_GREE_H_
@ -22,6 +24,11 @@
#endif #endif
// Constants // Constants
enum gree_ac_remote_model_t {
YAW1F = 1, // (1) Ultimate, EKOKAI, RusClimate (Default)
YBOFB, // (2) Green, YBOFB2, YAPOF3
};
const uint8_t kGreeAuto = 0; const uint8_t kGreeAuto = 0;
const uint8_t kGreeCool = 1; const uint8_t kGreeCool = 1;
const uint8_t kGreeDry = 2; const uint8_t kGreeDry = 2;
@ -37,7 +44,7 @@ const uint8_t kGreeSleepMask = 0b10000000;
// Byte 2 // Byte 2
const uint8_t kGreeTurboMask = 0b00010000; const uint8_t kGreeTurboMask = 0b00010000;
const uint8_t kGreeLightMask = 0b00100000; const uint8_t kGreeLightMask = 0b00100000;
const uint8_t kGreePower2Mask = 0b01000000; const uint8_t kGreePower2Mask = 0b01000000; // This might not be used. See #814
const uint8_t kGreeXfanMask = 0b10000000; const uint8_t kGreeXfanMask = 0b10000000;
// Byte 4 // Byte 4
const uint8_t kGreeSwingPosMask = 0b00001111; const uint8_t kGreeSwingPosMask = 0b00001111;
@ -87,8 +94,10 @@ const uint8_t kGreeSwingUpAuto = 0b00001011;
// Classes // Classes
class IRGreeAC { class IRGreeAC {
public: public:
explicit IRGreeAC(const uint16_t pin, const bool inverted = false, explicit IRGreeAC(
const bool use_modulation = true); const uint16_t pin,
const gree_ac_remote_model_t model = gree_ac_remote_model_t::YAW1F,
const bool inverted = false, const bool use_modulation = true);
void stateReset(void); void stateReset(void);
#if SEND_GREE #if SEND_GREE
@ -98,6 +107,8 @@ class IRGreeAC {
void begin(void); void begin(void);
void on(void); void on(void);
void off(void); void off(void);
void setModel(const gree_ac_remote_model_t model);
gree_ac_remote_model_t getModel(void);
void setPower(const bool on); void setPower(const bool on);
bool getPower(void); bool getPower(void);
void setTemp(const uint8_t temp); void setTemp(const uint8_t temp);
@ -142,6 +153,7 @@ class IRGreeAC {
#endif // UNIT_TEST #endif // UNIT_TEST
// The state of the IR remote in IR code form. // The state of the IR remote in IR code form.
uint8_t remote_state[kGreeStateLength]; uint8_t remote_state[kGreeStateLength];
gree_ac_remote_model_t _model;
void checksum(const uint16_t length = kGreeStateLength); void checksum(const uint16_t length = kGreeStateLength);
void fixup(void); void fixup(void);
}; };

Some files were not shown because too many files have changed in this diff Show More