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
[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
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.
## v2.6.4 Now Available
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
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
## _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)_
**[Bug Fixes]**

View File

@ -1,6 +1,6 @@
<!--- WARNING: Do NOT edit this file directly.
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
| 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 | | - |
| [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 |
| [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** | | | - |
| [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 |
@ -19,13 +19,15 @@
| [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** | | | - |
| [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) | **[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) | **[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) | **[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) | **[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) | **[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 |
| [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 | | - |
| [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 |
| [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** | | | - |
@ -33,6 +35,8 @@
| [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** | | | - |
| [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 |
| [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 |
@ -73,7 +77,9 @@
- CARRIER_AC
- COOLIX
- DAIKIN
- DAIKIN128
- DAIKIN160
- DAIKIN176
- DAIKIN2
- DAIKIN216
- DENON

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
name=IRremoteESP8266
version=2.6.3
version=2.6.4
author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff
maintainer=Mark Szabo, David Conran, Sebastien Warin, Roi Dayan, Massimiliano Pinto
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
case decode_type_t::DAIKIN:
#endif
#if SEND_DAIKIN128
case decode_type_t::DAIKIN128:
#endif
#if SEND_DAIKIN160
case decode_type_t::DAIKIN160:
#endif
@ -231,6 +234,32 @@ void IRac::daikin(IRDaikinESP *ac,
}
#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
void IRac::daikin160(IRDaikin160 *ac,
const bool on, const stdAc::opmode_t mode,
@ -408,11 +437,12 @@ void IRac::goodweather(IRGoodweatherAc *ac,
#endif // SEND_GOODWEATHER
#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 stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const bool turbo, const bool light, const bool clean,
const int16_t sleep) {
ac->setModel(model);
ac->setPower(on);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
@ -533,13 +563,15 @@ void IRac::kelvinator(IRKelvinatorAC *ac,
#if SEND_MIDEA
void IRac::midea(IRMideaAC *ac,
const bool on, const stdAc::opmode_t mode, const float degrees,
const stdAc::fanspeed_t fan, const int16_t sleep) {
const bool on, const stdAc::opmode_t mode, const bool celsius,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const int16_t sleep) {
ac->setPower(on);
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));
// No Vertical swing setting available.
ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff);
// No Horizontal swing setting available.
// No Quiet setting available.
// No Turbo setting available.
@ -558,13 +590,14 @@ void IRac::mitsubishi(IRMitsubishiAC *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees,
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
const stdAc::swingh_t swingh,
const bool quiet, const int16_t clock) {
ac->setPower(on);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setVane(ac->convertSwingV(swingv));
// No Horizontal swing setting available.
ac->setWideVane(ac->convertSwingH(swingh));
if (quiet) ac->setFan(kMitsubishiAcFanSilent);
// No Turbo 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.light = desired.light ^ prev->light;
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;
case decode_type_t::WHIRLPOOL_AC:
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);
break;
}
#endif // SEND_DAIKIN
#endif // SEND_ARGO
#if SEND_COOLIX
case COOLIX:
{
IRCoolixAC ac(_pin, _inverted, _modulation);
coolix(&ac, on, mode, degC, fan, swingv, swingh,
quiet, turbo, econo, clean);
turbo, light, clean, sleep);
break;
}
#endif // SEND_DAIKIN
#endif // SEND_COOLIX
#if SEND_DAIKIN
case DAIKIN:
{
@ -996,6 +1040,15 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
break;
}
#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
case DAIKIN160:
{
@ -1007,7 +1060,7 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
#if SEND_DAIKIN176
case DAIKIN176:
{
IRDaikin176 ac(_pin);
IRDaikin176 ac(_pin, _inverted, _modulation);
daikin176(&ac, on, mode, degC, fan, swingh);
break;
}
@ -1020,7 +1073,7 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
light, econo, filter, clean, beep, sleep, clock);
break;
}
#endif // SEND_DAIKIN216
#endif // SEND_DAIKIN2
#if SEND_DAIKIN216
case DAIKIN216:
{
@ -1061,9 +1114,10 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
#if SEND_GREE
case GREE:
{
IRGreeAC ac(_pin, _inverted, _modulation);
IRGreeAC ac(_pin, (gree_ac_remote_model_t)model, _inverted, _modulation);
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;
}
#endif // SEND_GREE
@ -1109,7 +1163,7 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
{
IRMideaAC ac(_pin, _inverted, _modulation);
ac.begin();
midea(&ac, on, mode, degC, fan, sleep);
midea(&ac, on, mode, celsius, degrees, fan, swingv, sleep);
break;
}
#endif // SEND_MIDEA
@ -1118,7 +1172,7 @@ bool IRac::sendAc(const decode_type_t vendor, const int16_t model,
{
IRMitsubishiAC ac(_pin, _inverted, _modulation);
ac.begin();
mitsubishi(&ac, on, mode, degC, fan, swingv, quiet, clock);
mitsubishi(&ac, on, mode, degC, fan, swingv, swingh, quiet, clock);
break;
}
#endif // SEND_MITSUBISHI_AC
@ -1515,6 +1569,13 @@ namespace IRAcUtils {
return ac.toString();
}
#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
case decode_type_t::DAIKIN160: {
IRDaikin160 ac(0);
@ -1847,7 +1908,7 @@ namespace IRAcUtils {
case decode_type_t::MIDEA: {
IRMideaAC ac(kGpioUnused);
ac.setRaw(decode->value); // Uses value instead of state.
*result = ac.toCommon();
*result = ac.toCommon(prev);
break;
}
#endif // DECODE_MIDEA

View File

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

View File

@ -647,6 +647,10 @@ bool IRrecv::decode(decode_results *results, irparams_t *save) {
DPRINTLN("Attempting Daikin176 decode");
if (decodeDaikin176(results)) return true;
#endif // DECODE_DAIKIN176
#if DECODE_DAIKIN128
DPRINTLN("Attempting Daikin128 decode");
if (decodeDaikin128(results)) return true;
#endif // DECODE_DAIKIN128
#if DECODE_HASH
// decodeHash returns a hash on any input.
// 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,
const bool strict = true);
#endif
#if DECODE_DAIKIN128
bool decodeDaikin128(decode_results *results,
const uint16_t nbits = kDaikin128Bits,
const bool strict = true);
#endif // DECODE_DAIKIN128
#if DECODE_DAIKIN160
bool decodeDaikin160(decode_results *results,
const uint16_t nbits = kDaikin160Bits,
const bool strict = true);
#endif // DECODE_DAIKIN160
#if DECODE_DAIKIN176
bool decodeDaikin176(decode_results *results,
const uint16_t nbits = kDaikin176Bits,
const bool strict = true);
bool decodeDaikin176(decode_results *results,
const uint16_t nbits = kDaikin176Bits,
const bool strict = true);
#endif // DECODE_DAIKIN176
#if DECODE_DAIKIN2
bool decodeDaikin2(decode_results *results, uint16_t nbits = kDaikin2Bits,

View File

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

View File

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

View File

@ -306,15 +306,20 @@ class IRsend {
const uint16_t nbytes = kDaikinStateLength,
const uint16_t repeat = kDaikinDefaultRepeat);
#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
void sendDaikin160(const unsigned char data[],
const uint16_t nbytes = kDaikin160StateLength,
const uint16_t repeat = kDaikin160DefaultRepeat);
#endif // SEND_DAIKIN160
#if SEND_DAIKIN176
void sendDaikin176(const unsigned char data[],
const uint16_t nbytes = kDaikin176StateLength,
const uint16_t repeat = kDaikin176DefaultRepeat);
void sendDaikin176(const unsigned char data[],
const uint16_t nbytes = kDaikin176StateLength,
const uint16_t repeat = kDaikin176DefaultRepeat);
#endif // SEND_DAIKIN176
#if SEND_DAIKIN2
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;
else if (!strcasecmp(str, "DAIKIN"))
return decode_type_t::DAIKIN;
else if (!strcasecmp(str, "DAIKIN128"))
return decode_type_t::DAIKIN128;
else if (!strcasecmp(str, "DAIKIN160"))
return decode_type_t::DAIKIN160;
else if (!strcasecmp(str, "DAIKIN176"))
@ -264,6 +266,9 @@ String typeToString(const decode_type_t protocol, const bool isRepeat) {
case DAIKIN:
result = F("DAIKIN");
break;
case DAIKIN128:
result = F("DAIKIN128");
break;
case DAIKIN160:
result = F("DAIKIN160");
break;
@ -464,6 +469,7 @@ bool hasACState(const decode_type_t protocol) {
switch (protocol) {
case ARGO:
case DAIKIN:
case DAIKIN128:
case DAIKIN160:
case DAIKIN176:
case DAIKIN2:
@ -917,4 +923,30 @@ namespace irutils {
result += uint64ToString(mins % 60);
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

View File

@ -56,5 +56,9 @@ namespace irutils {
String htmlEscape(const String unescaped);
String msToString(uint32_t const msecs);
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
#endif // IRUTILS_H_

View File

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

View File

@ -34,7 +34,11 @@ using irutils::addLabeledString;
using irutils::addModeToString;
using irutils::addTempToString;
using irutils::addFanToString;
using irutils::bcdToUint8;
using irutils::minsToString;
using irutils::sumNibbles;
using irutils::uint8ToBcd;
#if SEND_DAIKIN
// Send a Daikin A/C message.
@ -2019,6 +2023,7 @@ bool IRrecv::decodeDaikin160(decode_results *results, const uint16_t nbits,
return true;
}
#endif // DECODE_DAIKIN160
#if SEND_DAIKIN176
// 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
//
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(); }
@ -2103,10 +2110,12 @@ void IRDaikin176::stateReset() {
remote_state[8] = 0xDA;
remote_state[9] = 0x17;
remote_state[10] = 0x18;
remote_state[12] = 0x03;
remote_state[12] = 0x73;
remote_state[14] = 0x20;
remote_state[18] = 0x16; // Fan speed and swing
remote_state[20] = 0x20;
// remote_state[21] is a checksum byte, it will be set by checksum().
_saved_temp = getTemp();
}
uint8_t *IRDaikin176::getRaw() {
@ -2117,6 +2126,7 @@ uint8_t *IRDaikin176::getRaw() {
void IRDaikin176::setRaw(const uint8_t new_code[]) {
for (uint8_t i = 0; i < kDaikin176StateLength; i++)
remote_state[i] = new_code[i];
_saved_temp = getTemp();
}
#if SEND_DAIKIN176
@ -2126,19 +2136,16 @@ void IRDaikin176::send(const uint16_t repeat) {
}
#endif // SEND_DAIKIN176
void IRDaikin176::on() {
remote_state[kDaikin176BytePower] |= kDaikinBitPower;
}
void IRDaikin176::on() { setPower(true); }
void IRDaikin176::off() {
remote_state[kDaikin176BytePower] &= ~kDaikinBitPower;
}
void IRDaikin176::off() { setPower(false); }
void IRDaikin176::setPower(const bool state) {
remote_state[kDaikin176ByteModeButton] = 0;
if (state)
on();
remote_state[kDaikin176BytePower] |= kDaikinBitPower;
else
off();
remote_state[kDaikin176BytePower] &= ~kDaikinBitPower;
}
bool IRDaikin176::getPower() {
@ -2150,42 +2157,60 @@ uint8_t IRDaikin176::getMode() {
}
void IRDaikin176::setMode(const uint8_t mode) {
uint8_t altmode = 0;
switch (mode) {
case kDaikinAuto:
case kDaikin176Cool:
case kDaikinHeat:
case kDaikinFan:
case kDaikinDry:
remote_state[kDaikin176ByteMode] &= kDaikin176MaskMode;
remote_state[kDaikin176ByteMode] |= (mode << 4);
break;
default:
this->setMode(kDaikinAuto);
case kDaikinFan: altmode = 0; break;
case kDaikinDry: altmode = 7; break;
case kDaikin176Cool: altmode = 2; break;
default: this->setMode(kDaikin176Cool); return;
}
// 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.
uint8_t IRDaikin176::convertMode(const stdAc::opmode_t mode) {
switch (mode) {
case stdAc::opmode_t::kCool:
return kDaikin176Cool;
case stdAc::opmode_t::kHeat:
return kDaikinHeat;
case stdAc::opmode_t::kDry:
return kDaikinDry;
case stdAc::opmode_t::kHeat: // Heat not supported, but fan is the closest.
case stdAc::opmode_t::kFan:
return kDaikinFan;
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
void IRDaikin176::setTemp(const uint8_t temp) {
uint8_t degrees = std::max(temp, kDaikinMinTemp);
degrees = std::min(degrees, kDaikinMaxTemp) * 2 - 18;
uint8_t degrees = std::min(kDaikinMaxTemp, std::max(temp, kDaikinMinTemp));
_saved_temp = degrees;
switch (getMode()) {
case kDaikinDry:
case kDaikinFan:
degrees = kDaikin176DryFanTemp;
}
degrees = degrees * 2 - 18;
remote_state[kDaikin176ByteTemp] &= ~kDaikin176MaskTemp;
remote_state[kDaikin176ByteTemp] |= degrees;
remote_state[kDaikin176ByteModeButton] = 0;
}
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
void IRDaikin176::setFan(const uint8_t fan) {
uint8_t fanset;
if (fan == kDaikinFanQuiet || fan == kDaikinFanAuto)
fanset = fan;
else if (fan < kDaikinFanMin || fan > kDaikinFanMax)
fanset = kDaikinFanAuto;
else
fanset = 2 + fan;
// Set the fan speed bits, leave *lower* 4 bits alone
remote_state[kDaikin176ByteFan] &= ~kDaikin176MaskFan;
remote_state[kDaikin176ByteFan] |= (fanset << 4);
switch (fan) {
case kDaikinFanMin:
case kDaikin176FanMax:
remote_state[kDaikin176ByteFan] &= ~kDaikin176MaskFan;
remote_state[kDaikin176ByteFan] |= (fan << 4);
remote_state[kDaikin176ByteModeButton] = 0;
break;
default:
setFan(kDaikin176FanMax);
}
}
uint8_t IRDaikin176::getFan() {
uint8_t fan = remote_state[kDaikin176ByteFan] >> 4;
return fan;
}
uint8_t IRDaikin176::getFan() { return remote_state[kDaikin176ByteFan] >> 4; }
// Convert a standard A/C Fan speed into its native fan speed.
uint8_t IRDaikin176::convertFan(const stdAc::fanspeed_t speed) {
switch (speed) {
case stdAc::fanspeed_t::kMin: return kDaikinFanMin;
case stdAc::fanspeed_t::kLow: return kDaikinFanMin + 1;
case stdAc::fanspeed_t::kMedium: return kDaikinFanMin + 2;
case stdAc::fanspeed_t::kHigh: return kDaikinFanMax - 1;
case stdAc::fanspeed_t::kMax: return kDaikinFanMax;
switch (speed) {
case stdAc::fanspeed_t::kMin:
case stdAc::fanspeed_t::kLow:
return kDaikinFanMin;
default:
return kDaikinFanAuto;
return kDaikin176FanMax;
}
}
void IRDaikin176::setSwingHorizontal(const uint8_t position) {
switch (position) {
case kDaikin176SwingHSwing:
remote_state[kDaikin176ByteSwingH] &= kDaikin176MaskSwingH;
remote_state[kDaikin176ByteSwingH] |= position;
break;
default: setSwingHorizontal(kDaikin176SwingHAuto);
case kDaikin176SwingHOff:
case kDaikin176SwingHAuto:
remote_state[kDaikin176ByteSwingH] &= ~kDaikin176MaskSwingH;
remote_state[kDaikin176ByteSwingH] |= position;
break;
default:
setSwingHorizontal(kDaikin176SwingHAuto);
}
}
uint8_t IRDaikin176::getSwingHorizontal() {
return remote_state[kDaikin176ByteSwingH] & kDaikin176MaskSwingH;
}
@ -2241,7 +2264,9 @@ uint8_t IRDaikin176::getSwingHorizontal() {
uint8_t IRDaikin176::convertSwingH(const stdAc::swingh_t position) {
switch (position) {
case stdAc::swingh_t::kOff:
return kDaikin176SwingHSwing;
return kDaikin176SwingHOff;
case stdAc::swingh_t::kAuto:
return kDaikin176SwingHAuto;
default:
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.
stdAc::swingh_t IRDaikin176::toCommonSwingH(const uint8_t setting) {
switch (setting) {
case kDaikin176SwingHSwing: return stdAc::swingh_t::kOff;
default: return stdAc::swingh_t::kAuto;
case kDaikin176SwingHOff: return stdAc::swingh_t::kOff;
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.
stdAc::state_t IRDaikin176::toCommon(void) {
stdAc::state_t result;
result.protocol = decode_type_t::DAIKIN176;
result.model = -1; // No models used.
result.power = this->getPower();
result.mode = IRDaikinESP::toCommonMode(this->getMode());
result.mode = IRDaikin176::toCommonMode(this->getMode());
result.celsius = true;
result.degrees = this->getTemp();
result.fanspeed = IRDaikinESP::toCommonFanSpeed(this->getFan());
result.fanspeed = this->toCommonFanSpeed(this->getFan());
result.swingh = this->toCommonSwingH(this->getSwingHorizontal());
// Not supported.
@ -2283,60 +2316,24 @@ stdAc::state_t IRDaikin176::toCommon(void) {
// Convert the internal state into a human readable string.
String IRDaikin176::toString() {
String result = "";
result.reserve(120); // Reserve some heap for the string to reduce fragging.
result += F("Power: ");
if (this->getPower())
result += F("On");
else
result += F("Off");
result += F(", Mode: ");
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.reserve(80); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), F("Power"), false);
result += addModeToString(getMode(), kDaikinAuto, kDaikin176Cool, kDaikinHeat,
kDaikinDry, kDaikinFan);
result += addTempToString(getTemp());
result += addFanToString(getFan(), kDaikin176FanMax, kDaikinFanMin,
kDaikinFanMin, kDaikinFanMin, kDaikinFanMin);
result += F(", Swing (H): ");
result += uint64ToString(getSwingHorizontal());
switch (getSwingHorizontal()) {
case kDaikin176SwingHAuto:
result += F(" (Auto)");
break;
case kDaikin176SwingHSwing:
result += F(" (Off)");
break;
result += F(" (Auto)");
break;
case kDaikin176SwingHOff:
result += F(" (Off)");
break;
default:
result += F(" (UNKNOWN)");
}
return result;
}
@ -2400,3 +2397,519 @@ bool IRrecv::decodeDaikin176(decode_results *results, const uint16_t nbits,
return true;
}
#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: ARC423A5 remote
// 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_
#define IR_DAIKIN_H_
@ -257,18 +263,70 @@ const uint16_t kDaikin176Sections = 2;
const uint16_t kDaikin176Section1Length = 7;
const uint16_t kDaikin176Section2Length = kDaikin176StateLength -
kDaikin176Section1Length;
const uint8_t kDaikin176Cool = 0b111;
const uint8_t kDaikin176Cool = 0b111; // 7
const uint8_t kDaikin176BytePower = 14;
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 kDaikin176MaskTemp = 0b01111110;
const uint8_t kDaikin176DryFanTemp = 17; // Dry/Fan mode is always 17 Celsius.
const uint8_t kDaikin176ByteFan = 18;
const uint8_t kDaikin176MaskFan = 0b11110000;
const uint8_t kDaikin176FanMax = 3;
const uint8_t kDaikin176ByteSwingH = 18;
const uint8_t kDaikin176MaskSwingH = 0b00001111;
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.
#define DAIKIN_COOL kDaikinCool
@ -548,7 +606,8 @@ class IRDaikin160 {
// Class to emulate a Daikin BRC4C153 remote.
class IRDaikin176 {
public:
explicit IRDaikin176(uint16_t pin);
explicit IRDaikin176(const uint16_t pin, const bool inverted = false,
const bool use_modulation = true);
#if SEND_DAIKIN176
void send(const uint16_t repeat = kDaikin176DefaultRepeat);
@ -572,8 +631,10 @@ class IRDaikin176 {
uint8_t getFan(void);
static uint8_t convertFan(const stdAc::fanspeed_t speed);
void setSwingHorizontal(const uint8_t position);
uint8_t getSwingHorizontal();
uint8_t getSwingHorizontal(void);
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);
stdAc::state_t toCommon(void);
String toString(void);
@ -587,8 +648,77 @@ class IRDaikin176 {
#endif
// # of bytes per command
uint8_t remote_state[kDaikin176StateLength];
uint8_t _saved_temp;
void stateReset();
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_

View File

@ -113,9 +113,12 @@ void IRsend::sendGree(const uint64_t data, const uint16_t nbits,
}
#endif // SEND_GREE
IRGreeAC::IRGreeAC(const uint16_t pin, const bool inverted,
const bool use_modulation)
: _irsend(pin, inverted, use_modulation) { stateReset(); }
IRGreeAC::IRGreeAC(const uint16_t pin, const gree_ac_remote_model_t model,
const bool inverted, const bool use_modulation)
: _irsend(pin, inverted, use_modulation) {
stateReset();
setModel(model);
}
void IRGreeAC::stateReset(void) {
// 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) {
setPower(getPower()); // Redo the power bits as they differ between models.
checksum(); // Calculate the checksums
}
@ -149,6 +153,13 @@ void IRGreeAC::setRaw(const uint8_t new_code[]) {
for (uint8_t i = 0; i < kGreeStateLength; 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) {
@ -165,33 +176,45 @@ void IRGreeAC::checksum(const uint16_t length) {
// A boolean.
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.
if (state[length - 1] >> 4 ==
IRKelvinatorAC::calcBlockChecksum(state, length))
return true;
else
return false;
return (state[length - 1] >> 4 == IRKelvinatorAC::calcBlockChecksum(state,
length));
}
void IRGreeAC::on(void) {
remote_state[0] |= kGreePower1Mask;
remote_state[2] |= kGreePower2Mask;
void IRGreeAC::setModel(const gree_ac_remote_model_t model) {
switch (model) {
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) {
remote_state[0] &= ~kGreePower1Mask;
remote_state[2] &= ~kGreePower2Mask;
gree_ac_remote_model_t IRGreeAC::getModel(void) {
return _model;
}
void IRGreeAC::on(void) { setPower(true); }
void IRGreeAC::off(void) { setPower(false); }
void IRGreeAC::setPower(const bool on) {
if (on)
this->on();
else
this->off();
if (on) {
remote_state[0] |= kGreePower1Mask;
switch (_model) {
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) {
return (remote_state[0] & kGreePower1Mask) &&
(remote_state[2] & kGreePower2Mask);
// See #814. Not checking/requiring: (remote_state[2] & kGreePower2Mask)
return remote_state[0] & kGreePower1Mask;
}
// 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 result;
result.protocol = decode_type_t::GREE;
result.model = -1; // No models used.
result.model = this->getModel();
result.power = this->getPower();
result.mode = this->toCommonMode(this->getMode());
result.celsius = true;
@ -452,7 +475,13 @@ stdAc::state_t IRGreeAC::toCommon(void) {
String IRGreeAC::toString(void) {
String result = "";
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,
kGreeDry, kGreeFan);
result += addTempToString(getTemp());

View File

@ -6,6 +6,8 @@
// Brand: EKOKAI, Model: A/C
// Brand: RusClimate, Model: EACS/I-09HAR_X/N3 A/C
// Brand: RusClimate, Model: YAW1F remote
// Brand: Green, Model: YBOFB remote
// Brand: Green, Model: YBOFB2 remote
#ifndef IR_GREE_H_
#define IR_GREE_H_
@ -22,6 +24,11 @@
#endif
// 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 kGreeCool = 1;
const uint8_t kGreeDry = 2;
@ -37,7 +44,7 @@ const uint8_t kGreeSleepMask = 0b10000000;
// Byte 2
const uint8_t kGreeTurboMask = 0b00010000;
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;
// Byte 4
const uint8_t kGreeSwingPosMask = 0b00001111;
@ -87,8 +94,10 @@ const uint8_t kGreeSwingUpAuto = 0b00001011;
// Classes
class IRGreeAC {
public:
explicit IRGreeAC(const uint16_t pin, const bool inverted = false,
const bool use_modulation = true);
explicit IRGreeAC(
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);
#if SEND_GREE
@ -98,6 +107,8 @@ class IRGreeAC {
void begin(void);
void on(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);
bool getPower(void);
void setTemp(const uint8_t temp);
@ -142,6 +153,7 @@ class IRGreeAC {
#endif // UNIT_TEST
// The state of the IR remote in IR code form.
uint8_t remote_state[kGreeStateLength];
gree_ac_remote_model_t _model;
void checksum(const uint16_t length = kGreeStateLength);
void fixup(void);
};

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