Merge branch 'development' into pre-release-11.1

This commit is contained in:
Theo Arends 2022-04-07 17:10:14 +02:00
commit e8988e4b31
1118 changed files with 85843 additions and 28753 deletions

3
.gitattributes vendored
View File

@ -15,6 +15,3 @@
*.PDF diff=astextplain *.PDF diff=astextplain
*.rtf diff=astextplain *.rtf diff=astextplain
*.RTF diff=astextplain *.RTF diff=astextplain
# Apply Python syntax highlighting to berry (.be) files
*.be linguist-language=Python

View File

@ -7,7 +7,7 @@
- [ ] Only relevant files were touched - [ ] Only relevant files were touched
- [ ] Only one feature/fix was added per PR and the code change compiles without warnings - [ ] Only one feature/fix was added per PR and the code change compiles without warnings
- [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4.9 - [ ] The code change is tested and works with Tasmota core ESP8266 V.2.7.4.9
- [ ] The code change is tested and works with Tasmota core ESP32 V.2.0.2.1 - [ ] The code change is tested and works with Tasmota core ESP32 V.2.0.3
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla). - [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
_NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_ _NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_

View File

@ -22,6 +22,7 @@ jobs:
matrix: matrix:
variant: variant:
- tasmota - tasmota
- tasmota4M
- tasmota-minimal - tasmota-minimal
- tasmota-display - tasmota-display
- tasmota-ir - tasmota-ir
@ -36,7 +37,6 @@ jobs:
- tasmota32-display - tasmota32-display
- tasmota32-ir - tasmota32-ir
- tasmota32-lvgl - tasmota32-lvgl
- tasmota32-odroidgo
- tasmota32c3 - tasmota32c3
- tasmota32solo1 - tasmota32solo1
steps: steps:
@ -98,6 +98,7 @@ jobs:
mkdir -p ./firmware/map mkdir -p ./firmware/map
[ ! -f ./mv_firmware/map/* ] || mv ./mv_firmware/map/* ./firmware/map/ [ ! -f ./mv_firmware/map/* ] || mv ./mv_firmware/map/* ./firmware/map/
[ ! -f ./mv_firmware/firmware/tasmota.* ] || mv ./mv_firmware/firmware/tasmota.* ./firmware/tasmota/ [ ! -f ./mv_firmware/firmware/tasmota.* ] || mv ./mv_firmware/firmware/tasmota.* ./firmware/tasmota/
[ ! -f ./mv_firmware/firmware/tasmota4M.* ] || mv ./mv_firmware/firmware/tasmota4M.* ./firmware/tasmota/
[ ! -f ./mv_firmware/firmware/tasmota-sensors.* ] || mv ./mv_firmware/firmware/tasmota-sensors.* ./firmware/tasmota/ [ ! -f ./mv_firmware/firmware/tasmota-sensors.* ] || mv ./mv_firmware/firmware/tasmota-sensors.* ./firmware/tasmota/
[ ! -f ./mv_firmware/firmware/tasmota-minimal.bin.gz ] || mv ./mv_firmware/firmware/tasmota-minimal.bin.gz ./firmware/tasmota/ [ ! -f ./mv_firmware/firmware/tasmota-minimal.bin.gz ] || mv ./mv_firmware/firmware/tasmota-minimal.bin.gz ./firmware/tasmota/
[ ! -f ./mv_firmware/firmware/tasmota-lite.* ] || mv ./mv_firmware/firmware/tasmota-lite.* ./firmware/tasmota/ [ ! -f ./mv_firmware/firmware/tasmota-lite.* ] || mv ./mv_firmware/firmware/tasmota-lite.* ./firmware/tasmota/

View File

@ -21,6 +21,7 @@ jobs:
matrix: matrix:
variant: variant:
- tasmota - tasmota
- tasmota4M
- tasmota-minimal - tasmota-minimal
- tasmota-display - tasmota-display
- tasmota-ir - tasmota-ir
@ -35,7 +36,6 @@ jobs:
- tasmota32-display - tasmota32-display
- tasmota32-ir - tasmota32-ir
- tasmota32-lvgl - tasmota32-lvgl
- tasmota32-odroidgo
- tasmota32c3 - tasmota32c3
- tasmota32solo1 - tasmota32solo1
steps: steps:
@ -106,6 +106,7 @@ jobs:
mkdir -p ./release-firmware/map mkdir -p ./release-firmware/map
[ ! -f ./mv_firmware/map/* ] || mv ./mv_firmware/map/* ./release-firmware/map/ [ ! -f ./mv_firmware/map/* ] || mv ./mv_firmware/map/* ./release-firmware/map/
[ ! -f ./mv_firmware/firmware/tasmota.* ] || mv ./mv_firmware/firmware/tasmota.* ./release-firmware/tasmota/ [ ! -f ./mv_firmware/firmware/tasmota.* ] || mv ./mv_firmware/firmware/tasmota.* ./release-firmware/tasmota/
[ ! -f ./mv_firmware/firmware/tasmota4M.* ] || mv ./mv_firmware/firmware/tasmota4M.* ./release-firmware/tasmota/
[ ! -f ./mv_firmware/firmware/tasmota-sensors.* ] || mv ./mv_firmware/firmware/tasmota-sensors.* ./release-firmware/tasmota/ [ ! -f ./mv_firmware/firmware/tasmota-sensors.* ] || mv ./mv_firmware/firmware/tasmota-sensors.* ./release-firmware/tasmota/
[ ! -f ./mv_firmware/firmware/tasmota-minimal.bin.gz ] || mv ./mv_firmware/firmware/tasmota-minimal.bin.gz ./release-firmware/tasmota/ [ ! -f ./mv_firmware/firmware/tasmota-minimal.bin.gz ] || mv ./mv_firmware/firmware/tasmota-minimal.bin.gz ./release-firmware/tasmota/
[ ! -f ./mv_firmware/firmware/tasmota-lite.* ] || mv ./mv_firmware/firmware/tasmota-lite.* ./release-firmware/tasmota/ [ ! -f ./mv_firmware/firmware/tasmota-lite.* ] || mv ./mv_firmware/firmware/tasmota-lite.* ./release-firmware/tasmota/

View File

@ -24,6 +24,7 @@ jobs:
matrix: matrix:
variant: variant:
- tasmota - tasmota
- tasmota4M
- tasmota-display - tasmota-display
- tasmota-ir - tasmota-ir
- tasmota-knx - tasmota-knx
@ -39,7 +40,7 @@ jobs:
- tasmota32-display - tasmota32-display
- tasmota32-ir - tasmota32-ir
- tasmota32-lvgl - tasmota32-lvgl
- tasmota32-odroidgo - tasmota32s2
- tasmota32c3 - tasmota32c3
- tasmota32solo1 - tasmota32solo1
steps: steps:

View File

@ -9,6 +9,7 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| Feature or Sensor | l | t | k | s | i | d | Remarks | Feature or Sensor | l | t | k | s | i | d | Remarks
|-----------------------|---|-------|---|---|---|---|-------- |-----------------------|---|-------|---|---|---|---|--------
| MY_LANGUAGE en_GB | x | x / x | x | x | x | x | | MY_LANGUAGE en_GB | x | x / x | x | x | x | x |
| USE_IMPROV | - | x / x | x | x | x | x |
| USE_UFILESYS | - | - / x | - | - | - | - | | USE_UFILESYS | - | - / x | - | - | - | - |
| USE_ARDUINO_OTA | - | - / - | - | - | - | - | | USE_ARDUINO_OTA | - | - / - | - | - | - | - |
| USE_DOMOTICZ | - | x / x | x | x | x | - | | USE_DOMOTICZ | - | x / x | x | x | x | - |
@ -19,7 +20,6 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_TELEGRAM | - | - / - | - | - | - | - | | USE_TELEGRAM | - | - / - | - | - | - | - |
| USE_KNX | - | - / x | x | - | - | - | | USE_KNX | - | - / x | x | - | - | - |
| USE_WEBSERVER | x | x / x | x | x | x | x | | USE_WEBSERVER | x | x / x | x | x | x | x |
| USE_JAVASCRIPT_ES6 | - | - / - | - | - | - | - |
| USE_WEBSEND_RESPONSE | - | - / - | - | - | - | - | | USE_WEBSEND_RESPONSE | - | - / - | - | - | - | - |
| USE_EMULATION_HUE | x | x / x | - | x | - | - | | USE_EMULATION_HUE | x | x / x | - | x | - | - |
| USE_EMULATION_WEMO | x | x / x | - | x | - | - | | USE_EMULATION_WEMO | x | x / x | - | x | - | - |
@ -127,8 +127,10 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_SCD30 | - | - / x | - | x | - | - | | USE_SCD30 | - | - / x | - | x | - | - |
| USE_SCD40 | - | - / x | - | - | - | - | | USE_SCD40 | - | - / x | - | - | - | - |
| USE_SPS30 | - | - / - | - | - | - | - | | USE_SPS30 | - | - / - | - | - | - | - |
| USE_ADE7880 | - | - / - | - | - | - | - |
| USE_ADE7953 | - | x / x | x | x | - | x | | USE_ADE7953 | - | x / x | x | x | - | x |
| USE_VL53L0X | - | - / x | - | x | - | - | | USE_VL53L0X | - | - / x | - | x | - | - |
| USE_VL53L1X | - | - / - | - | - | - | - |
| USE_MLX90614 | - | - / - | - | - | - | - | | USE_MLX90614 | - | - / - | - | - | - | - |
| USE_CHIRP | - | - / - | - | - | - | - | | USE_CHIRP | - | - / - | - | - | - | - |
| USE_PAJ7620 | - | - / - | - | - | - | - | | USE_PAJ7620 | - | - / - | - | - | - | - |
@ -161,9 +163,13 @@ Note: `minimal` variant is not listed as it shouldn't be used outside of the [up
| USE_EZORTD | - | - / - | - | - | - | - | | USE_EZORTD | - | - / - | - | - | - | - |
| USE_SEESAW_SOIL | - | - / - | - | - | - | - | | USE_SEESAW_SOIL | - | - / - | - | - | - | - |
| USE_TOF10120 | - | - / - | - | - | - | - | | USE_TOF10120 | - | - / - | - | - | - | - |
| USE_BM8563 | - | - / - | - | - | - | - |
| USE_AM2320 | - | - / - | - | - | - | - | | USE_AM2320 | - | - / - | - | - | - | - |
| USE_T67XX | - | - / - | - | - | - | - | | USE_T67XX | - | - / - | - | - | - | - |
| USE_HM330X | - | - / - | - | - | - | - | | USE_HM330X | - | - / - | - | - | - | - |
| USE_HDC2010 | - | - / - | - | - | - | - |
| USE_PCF85363 | - | - / - | - | - | - | - |
| USE_DS3502 | - | - / - | - | - | - | - |
| | | | | | | | | | | | | | | |
| Feature or Sensor | l | t | k | s | i | d | Remarks | Feature or Sensor | l | t | k | s | i | d | Remarks
| USE_SPI | - | - / - | - | - | - | x | | USE_SPI | - | - / - | - | - | - | x |

View File

@ -3,17 +3,101 @@ All notable changes to this project will be documented in this file.
## [Released] ## [Released]
## [11.1.0] 20220413
- Release Ostara
## [11.0.0.6] 20220413
### Added
- Commands ``Sensor34 10 <valueA>`` and ``Sensor34 11 <valueB>`` to use HX711 absolute weight conversion (#15292)
## [11.0.0.5] 20220407
### Added
- Support for improv as used by esp-web-tools
- Command ``IfxSensor 1`` to send non-teleperiod data to influxdb
- ESP32 Support for OpenHASP v1.0 by Stephan Hadinger (#15307)
### Changed
- Remove support for Internet Explorer by allowing ECMAScript6 syntax using less JavaScript code bytes (#15280)
### Fixed
- ESP32 save settings after OTA upload regression from v10.0.0.3
- HX711 false readings by removing large deviations
## [11.0.0.4] 20220402
### Added
- Command ``RtcNtpserver 0/1`` to enable Tasmota NTP server when enabled by define ``RTC_NTP_SERVER``
- NeoPool JSON modules, power module, cell info, chlorine, conductivity and ionization
- Support for up to four DS3502 digital potentiometers with command ``Wiper<x> 0..127``
- Command ``SetOption136 1`` to disable single sensor reports from Tuya devices while keeping teleperiod reports (#15216)
### Changed
- Consolidate three RTC chip drivers (DS3231, BM8563, PCF85363) into one driver updating RTC as soon as possible after restart
- Removed command ``Sensor33`` and replaced by ``RtcNtpserver``
- DS3231 I2C address define ``USE_RTC_ADDR`` into ``DS3231_ADDRESS``
- NeoPool remove ambiguous device color names
- Display of energy values in GUI use columns when define ``USE_ENERGY_COLUMN_GUI`` is enabled (default)
- IRremoteESP8266 library from v2.8.1 to v2.8.2
- Tasmota ESP32 Arduino core to v2.0.3
- ESP8266 Shrinked tasmota-minimal.bin by removing all commands except ``Upgrade``, ``Upload``, ``OtaUrl``, ``Seriallog``, ``Weblog`` and ``Restart``
### Fixed
- NeoPool NPBit and NPRead/NPReadL output
- ESP32 PowerOnState (#15084)
## [11.0.0.3] 20220312
### Added
- TasmotaSerial implement ``end()``
- ESP32 TasmotaSerial uart mapping to support multiple ``begin()`` and implement ``getUart()`` (#14981)
- Commands ``Sensor12 D0 .. D5, S0 .. S5`` allowing differential or single-ended modes (#15001)
- NeoPool commands ``NPpHMin``, ``NPpHMax``, ``NPpH``, ``NPRedox``, ``NPHydrolysis``, ``NPIonization``, ``NPChlorine`` and ``NPControl`` (#15015)
- NeoPool system voltages display
- Full DS3231 integration and synchronisation when using UBX (=GPS), NTP or manual time
- LVGL Splash screen and ``SetOption135 1`` to disable splash screen
- Command ``RfTimeout 100..60000`` to disable duplicate RfReceive. Default 1000 (#15061)
- Support for ADE7880 3 phase energy monitor as used in Shelly 3EM (#13515)
- Support for PCF85363 RTC as used in Shelly 3EM (#13515)
### Changed
- Extent number of pulsetimers from 8 to 32 (#8266)
- Tasmota ESP32 Arduino core to v2.0.2.3 (#14979)
- TasmotaSerial library from v3.4.0 to v3.5.0 (#14981)
- NeoPool limit relay output to the number actually available
## [11.0.0.2] 20220225
### Changed
- Enabled ethernet and Sonoff SPM in ``tasmota32.bin``
## [11.0.0.1] 20220220
### Added
- Command ``SspmMap 0`` to reset Sonoff SPM default mapping
- Command ``TcpConnect <port><ip_address>`` to add client connection mode (#14874)
- ESP32 support for BLE Mi scale V1 (#13517)
- ESP32 integrate Homekit in Bluetooth binary (#14818)
- ESP32 Berry always enable rules
- ESP32 Berry bootloop protection
- ESP32 Berry virtual Alexa hue device (#14833)
### Changed
- Adafruit BusIO library from v1.0.10 to v1.11.0
- ESP32 update the internal Berry type system to sync with Skiars Berry repository. No expected impact on code, but .bec files need to be generated again. (#14811)
- ESP32 LVGL library from v8.1.0 to v8.2.0
- ESP32 NimBLE library from v1.3.3 to v1.3.6
- Sonoff SPM increase max number of relays supported to 32 (8 SPM-4Relay modules)
### Fixed
- SSPM energy yesterday when zero
- GPIO OptionE1 selection regression (#14821)
- BL0939, BL0940 and BL0942 energy monitoring buffer miscompares resulting in wrong daily energy values regression from v9.5.0.8 (#14829)
- Orno WE517 power meter phase 2 current reactive (#14841)
- Wiegand 34-bit rfid reading and presentation (#14834)
## [11.0.0] 20220212 ## [11.0.0] 20220212
- Release Olivia - Release Olivia
## [10.1.0.8] 20220212 ## [10.1.0.8] 20220212
### Added
### Changed ### Changed
- From Calendar Versioning (CalVer) back to Semantic Versioning (SemVer) for better major change indication and future support - From Calendar Versioning (CalVer) back to Semantic Versioning (SemVer) for better major change indication and future support
### Fixed
## [2022.1.4 = 10.1.0.7] 20220205 ## [2022.1.4 = 10.1.0.7] 20220205
### Added ### Added
- Rule variables %timer1% to %timer16% (#14619) - Rule variables %timer1% to %timer16% (#14619)

View File

@ -98,3 +98,6 @@ Index | Define | Driver | Device | Address(es) | Description
62 | USE_SCD40 | xsns_92 | SCD40 | 0x62 | CO2 sensor Sensirion SCD40/SCD41 62 | USE_SCD40 | xsns_92 | SCD40 | 0x62 | CO2 sensor Sensirion SCD40/SCD41
63 | USE_HM330X | xsns_93 | HM330X | 0x40 | Particule sensor 63 | USE_HM330X | xsns_93 | HM330X | 0x40 | Particule sensor
64 | USE_HDC2010 | xsns_94 | HDC2010 | 0x40 | Temperature and Humidity sensor 64 | USE_HDC2010 | xsns_94 | HDC2010 | 0x40 | Temperature and Humidity sensor
65 | USE_ADE7880 | xnrg_23 | ADE7880 | 0x38 | Energy monitor
66 | USE_PCF85363 | xsns_99 | PCF85363 | 0x51 | Real time clock
67 | USE_DS3502 | xdrv_61 | DS3502 | 0x28 - 0x2B | Digital potentiometer

View File

@ -9,6 +9,16 @@ _Written for PlatformIO with limited support for Arduino IDE._
[![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4) [![Chat](https://img.shields.io/discord/479389167382691863.svg)](https://discord.gg/Ks2Kzd4)
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/arendst/Tasmota) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/arendst/Tasmota)
<hr></hr>
**In light of current events we like to support the people behind _PlatformIO Project_, especially Ivan Kravets, and wish them the strength to help stop the war. See [platformio-is-ukrainian-project-please-help-us-stop-the-war](https://community.platformio.org/t/platformio-is-ukrainian-project-please-help-us-stop-the-war/26330) for what you can do.**
<hr></hr>
## Easy install
Easy initial installation of Tasmota can be performed using the [Tasmota WebInstaller](https://arendst.github.io/Tasmota-firmware/).
If you like **Tasmota**, give it a star, or fork it and contribute! If you like **Tasmota**, give it a star, or fork it and contribute!
[![GitHub stars](https://img.shields.io/github/stars/arendst/Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Tasmota/stargazers) [![GitHub stars](https://img.shields.io/github/stars/arendst/Tasmota.svg?style=social&label=Star)](https://github.com/arendst/Tasmota/stargazers)
@ -19,8 +29,6 @@ See [RELEASENOTES.md](https://github.com/arendst/Tasmota/blob/master/RELEASENOTE
Firmware binaries can be downloaded from http://ota.tasmota.com/tasmota/release/ or http://ota.tasmota.com/tasmota32/release/ for ESP32 binaries. Firmware binaries can be downloaded from http://ota.tasmota.com/tasmota/release/ or http://ota.tasmota.com/tasmota32/release/ for ESP32 binaries.
Easy initial installation of Tasmota can be performed using the [Tasmota WebInstaller](https://arendst.github.io/Tasmota-firmware/).
## Development ## Development
[![Dev Version](https://img.shields.io/badge/development%20version-v11.0.x.x-blue.svg)](https://github.com/arendst/Tasmota) [![Dev Version](https://img.shields.io/badge/development%20version-v11.0.x.x-blue.svg)](https://github.com/arendst/Tasmota)
@ -38,7 +46,7 @@ Note that there is a chance, as with any upgrade, that the device may not functi
## Disclaimer ## Disclaimer
:warning: **DANGER OF ELECTROCUTION** :warning: st:warning: **DANGER OF ELECTROCUTION** :warning:
If your device connects to mains electricity (AC power) there is danger of electrocution if not installed properly. If you don't know how to install it, please call an electrician (***Beware:*** certain countries prohibit installation without a licensed electrician present). Remember: _**SAFETY FIRST**_. It is not worth the risk to yourself, your family and your home if you don't know exactly what you are doing. Never tinker or try to flash a device using the serial programming interface while it is connected to MAINS ELECTRICITY (AC power). If your device connects to mains electricity (AC power) there is danger of electrocution if not installed properly. If you don't know how to install it, please call an electrician (***Beware:*** certain countries prohibit installation without a licensed electrician present). Remember: _**SAFETY FIRST**_. It is not worth the risk to yourself, your family and your home if you don't know exactly what you are doing. Never tinker or try to flash a device using the serial programming interface while it is connected to MAINS ELECTRICITY (AC power).
@ -73,17 +81,17 @@ Pay attention to the following version breaks due to dynamic settings updates:
1. Migrate to **Sonoff-Tasmota 3.9.x** 1. Migrate to **Sonoff-Tasmota 3.9.x**
2. Migrate to **Sonoff-Tasmota 4.x** 2. Migrate to **Sonoff-Tasmota 4.x**
3. Migrate to **Sonoff-Tasmota 5.14** 3. Migrate to **Sonoff-Tasmota 5.14**
4. Migrate to **Sonoff-Tasmota 6.7.1** (http://ota.tasmota.com/tasmota/release-6.7.1/) 4. Migrate to **Sonoff-Tasmota 6.7.1** (http://ota.tasmota.com/tasmota/release_6.7.1/sonoff.bin) - NOTICE underscore as a dash is not supported in older versions
5. Migrate to **Tasmota 7.2.0** (http://ota.tasmota.com/tasmota/release-7.2.0/) 5. Migrate to **Tasmota 7.2.0** (http://ota.tasmota.com/tasmota/release-7.2.0/tasmota.bin)
--- Major change in parameter storage layout --- --- Major change in parameter storage layout ---
6. Migrate to **Tasmota 8.5.1** (http://ota.tasmota.com/tasmota/release-8.5.1/) 6. Migrate to **Tasmota 8.5.1** (http://ota.tasmota.com/tasmota/release-8.5.1/tasmota.bin)
--- Major change in internal GPIO function representation --- --- Major change in internal GPIO function representation ---
7. Migrate to **Tasmota 9.1** (http://ota.tasmota.com/tasmota/release-9.1.0/) 7. Migrate to **Tasmota 9.1** (http://ota.tasmota.com/tasmota/release-9.1.0/tasmota.bin.gz)
8. Upgrade to **latest release** (http://ota.tasmota.com/tasmota/release/) 8. Upgrade to **latest release** (http://ota.tasmota.com/tasmota/release/tasmota.bin.gz)
While fallback or downgrading is common practice it was never supported due to Settings additions or changes in newer releases. Starting with release **v9.1.0 Imogen** the internal GPIO function representation has changed in such a way that fallback is only possible to the latest GPIO configuration before installing **v9.1.0**. While fallback or downgrading is common practice it was never supported due to Settings additions or changes in newer releases. Starting with release **v9.1.0 Imogen** the internal GPIO function representation has changed in such a way that fallback is only possible to the latest GPIO configuration before installing **v9.1.0**.

View File

@ -15,17 +15,17 @@ Pay attention to the following version breaks due to dynamic settings updates:
1. Migrate to **Sonoff-Tasmota 3.9.x** 1. Migrate to **Sonoff-Tasmota 3.9.x**
2. Migrate to **Sonoff-Tasmota 4.x** 2. Migrate to **Sonoff-Tasmota 4.x**
3. Migrate to **Sonoff-Tasmota 5.14** 3. Migrate to **Sonoff-Tasmota 5.14**
4. Migrate to **Sonoff-Tasmota 6.7.1** (http://ota.tasmota.com/tasmota/release-6.7.1/) 4. Migrate to **Sonoff-Tasmota 6.7.1** (http://ota.tasmota.com/tasmota/release_6.7.1/sonoff.bin) - NOTICE underscore as a dash is not supported in older versions
5. Migrate to **Tasmota 7.2.0** (http://ota.tasmota.com/tasmota/release-7.2.0/) 5. Migrate to **Tasmota 7.2.0** (http://ota.tasmota.com/tasmota/release-7.2.0/tasmota.bin)
--- Major change in parameter storage layout --- --- Major change in parameter storage layout ---
6. Migrate to **Tasmota 8.5.1** (http://ota.tasmota.com/tasmota/release-8.5.1/) 6. Migrate to **Tasmota 8.5.1** (http://ota.tasmota.com/tasmota/release-8.5.1/tasmota.bin)
--- Major change in internal GPIO function representation --- --- Major change in internal GPIO function representation ---
7. Migrate to **Tasmota 9.1** (http://ota.tasmota.com/tasmota/release-9.1.0/) 7. Migrate to **Tasmota 9.1** (http://ota.tasmota.com/tasmota/release-9.1.0/tasmota.bin.gz)
8. Upgrade to **latest release** (http://ota.tasmota.com/tasmota/release/) 8. Upgrade to **latest release** (http://ota.tasmota.com/tasmota/release/tasmota.bin.gz)
While fallback or downgrading is common practice it was never supported due to Settings additions or changes in newer releases. Starting with release **v9.1.0 Imogen** the internal GPIO function representation has changed in such a way that fallback is only possible to the latest GPIO configuration before installing **v9.1.0**. While fallback or downgrading is common practice it was never supported due to Settings additions or changes in newer releases. Starting with release **v9.1.0 Imogen** the internal GPIO function representation has changed in such a way that fallback is only possible to the latest GPIO configuration before installing **v9.1.0**.
@ -71,12 +71,12 @@ Latest released binaries can be downloaded from
- http://ota.tasmota.com/tasmota/release - http://ota.tasmota.com/tasmota/release
Historical binaries can be downloaded from Historical binaries can be downloaded from
- http://ota.tasmota.com/tasmota/release-11.0.0 - http://ota.tasmota.com/tasmota/release-11.1.0
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz`` The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz``
### ESP32 based ### ESP32 based
The following binary downloads have been compiled with ESP32/Arduino library core version **2.0.2.1**. The following binary downloads have been compiled with ESP32/Arduino library core version **2.0.3**.
- **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY** - **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY**
- **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3 and 4M+ flash. - **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3 and 4M+ flash.
@ -93,7 +93,7 @@ Latest released binaries can be downloaded from
- http://ota.tasmota.com/tasmota32/release - http://ota.tasmota.com/tasmota32/release
Historical binaries can be downloaded from Historical binaries can be downloaded from
- http://ota.tasmota.com/tasmota32/release-11.0.0 - http://ota.tasmota.com/tasmota32/release-11.1.0
The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota32/release/tasmota32.bin`` The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota32/release/tasmota32.bin``
@ -103,74 +103,60 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
[Complete list](BUILDS.md) of available feature and sensors. [Complete list](BUILDS.md) of available feature and sensors.
## Changelog v11.0.0 Olivia ## Changelog v11.1.0 Ostara
### Added ### Added
- Command ``Json {<Tasmota commands>}`` to enable input of any command as JSON tokens [#14568](https://github.com/arendst/Tasmota/issues/14568) - Command ``SetOption135 1`` to disable LVGL splash screen
- Command ``SetOption44 1..100`` to set base tolerance percentage for matching incoming IR messages (default 25, max 100) [#14555](https://github.com/arendst/Tasmota/issues/14555) - Command ``SetOption136 1`` to disable single sensor reports from Tuya devices while keeping teleperiod reports [#15216](https://github.com/arendst/Tasmota/issues/15216)
- Command ``SetOption134 1`` to disable PWM auto-phasing for lights by default (new behavior) [#14590](https://github.com/arendst/Tasmota/issues/14590) - Command ``SspmMap 0`` to reset Sonoff SPM default mapping
- Command ``SSerialConfig <serialconfig>`` to change Serial Bridge configuration - Command ``TcpConnect <port><ip_address>`` to add client connection mode [#14874](https://github.com/arendst/Tasmota/issues/14874)
- Command ``SspmDisplay 1`` to display Sonoff SPM energy data in GUI for relays powered on only - Command ``RfTimeout 100..60000`` to disable duplicate RfReceive. Default 1000 [#15061](https://github.com/arendst/Tasmota/issues/15061)
- Command ``SspmEnergyTotal<relay>`` to (p)reset Sonoff SPM total energy without today's energy - Command ``IfxSensor 1`` to send non-teleperiod data to influxdb
- Command ``SspmEnergyYesterday<relay>`` to (p)reset Sonoff SPM energy yesterday - Commands ``Sensor12 D0 .. D5, S0 .. S5`` allowing differential or single-ended modes [#15001](https://github.com/arendst/Tasmota/issues/15001)
- Command ``SspmHistory<relay>`` to retrieve Sonoff SPM daily energy up to last six month (as defined by ARM firmware) - Commands ``Sensor34 10 <valueA>`` and ``Sensor34 11 <valueB>`` to use HX711 absolute weight conversion [#15292](https://github.com/arendst/Tasmota/issues/15292)
- Command ``SspmIAmHere<relay>`` to (faintly) blink Sonoff SPM-4Relay module error light of requested relay - NeoPool commands ``NPpHMin``, ``NPpHMax``, ``NPpH``, ``NPRedox``, ``NPHydrolysis``, ``NPIonization``, ``NPChlorine`` and ``NPControl`` [#15015](https://github.com/arendst/Tasmota/issues/15015)
- Command ``SspmLog<relay> [x]`` to retrieve Sonoff SPM relay power state change and cause logging - NeoPool system voltages display
- Command ``SspmMap 2,1,..`` to map Sonoff SPM scanned module to physical module [#14281](https://github.com/arendst/Tasmota/issues/14281) - TasmotaSerial implement ``end()``
- Command ``SspmOverload<relay> <options>`` to set Sonoff SPM overload criteria for any relay - Support for improv as used by esp-web-tools
- Command ``SspmScan`` to rescan Sonoff SPM modbus - Support for up to four DS3502 digital potentiometers with command ``Wiper<x> 0..127``
- Command ``WebTime <start_pos>,<end_pos>`` to show part of date and/or time in web gui based on "2017-03-07T11:08:02-07:00" - Support for ADE7880 3 phase energy monitor as used in Shelly 3EM [#13515](https://github.com/arendst/Tasmota/issues/13515)
- Commands for ESP32 ethernet configuration ``EthIpAddress``, ``EthGateway``, ``EthSubnetmask``, ``EthDnsServer1`` and ``EthDnsServer2`` [#14385](https://github.com/arendst/Tasmota/issues/14385) - Support for PCF85363 RTC as used in Shelly 3EM [#13515](https://github.com/arendst/Tasmota/issues/13515)
- Support for Eastron SDM230 modBus energy meter [#13443](https://github.com/arendst/Tasmota/issues/13443) - Full RTC chip integration and synchronisation when using UBX (=GPS), NTP or manual time
- PWM Dimmer two button support [#13993](https://github.com/arendst/Tasmota/issues/13993) - NeoPool JSON modules, power module, cell info, chlorine, conductivity and ionization
- Support for Linkind dimmer as GPIO ``Option A6`` [#14004](https://github.com/arendst/Tasmota/issues/14004) - ESP32 Berry always enable rules
- DDP schemes for light and WS2812 [#14017](https://github.com/arendst/Tasmota/issues/14017) - ESP32 Berry bootloop protection
- Device Group Send full status item [#14045](https://github.com/arendst/Tasmota/issues/14045) - ESP32 Support for OpenHASP v1.0 by Stephan Hadinger [#15307](https://github.com/arendst/Tasmota/issues/15307)
- Support for MAX7219 Dot Matrix displays [#14091](https://github.com/arendst/Tasmota/issues/14091) - ESP32 support for BLE Mi scale V1 [#13517](https://github.com/arendst/Tasmota/issues/13517)
- Experimental ADE7953 (Shelly EM) reset on restart [#14261](https://github.com/arendst/Tasmota/issues/14261) - ESP32 integrate Homekit in Bluetooth binary [#14818](https://github.com/arendst/Tasmota/issues/14818)
- Solax X1 negative temperature support [#14278](https://github.com/arendst/Tasmota/issues/14278) - ESP32 Berry virtual Alexa hue device [#14833](https://github.com/arendst/Tasmota/issues/14833)
- Solax X1 modbus RTS support and offline status [#14305](https://github.com/arendst/Tasmota/issues/14305) - ESP32 TasmotaSerial uart mapping to support multiple ``begin()`` and implement ``getUart()`` [#14981](https://github.com/arendst/Tasmota/issues/14981)
- Tasmota favicon to webbrowser tab [#14322](https://github.com/arendst/Tasmota/issues/14322)
- Support for BME688 with latest Bosch-Sensor-API library [#14513](https://github.com/arendst/Tasmota/issues/14513)
- Rule variable %color% [#14572](https://github.com/arendst/Tasmota/issues/14572)
- Rule variables %timer1% to %timer16% [#14619](https://github.com/arendst/Tasmota/issues/14619)
- Support for MQ analog sensor for air quality by Francesco Adriani [#14581](https://github.com/arendst/Tasmota/issues/14581)
- ESP32 single binary firmware [#14239](https://github.com/arendst/Tasmota/issues/14239)
- ESP32 disable serial console when 3 (ESP32) or 2 (Other models) serial interfaces are requested [#14487](https://github.com/arendst/Tasmota/issues/14487)
- ESP32 support for TuyaMcu
- ESP32 Berry features
- ESP32 support for USE_PWM_DIMMER as GPIO ``Option E1``
- ESP32 increase PWM channels to 16
- ESP32 auto-configuration
- ESP32 initial support for ESP32S3 with support for 38 configurable GPIOs
### Breaking Changed ### Breaking Changed
### Changed ### Changed
- ESP32 core library from v2.0.2 to v2.0.2.1 - Adafruit BusIO library from v1.0.10 to v1.11.0
- PubSubClient library from v2.8.12 to v2.8.13 - TasmotaSerial library from v3.4.0 to v3.5.0 [#14981](https://github.com/arendst/Tasmota/issues/14981)
- TasmotaSerial library from v3.3.0 to v3.4.0 - Sonoff SPM increase max number of relays supported to 32 (8 SPM-4Relay modules)
- TasmotaModbus library from v1.2.0 to v3.4.0 - Extent number of pulsetimers from 8 to 32 [#8266](https://github.com/arendst/Tasmota/issues/8266)
- ESP8266Audio library from v1.9.2 to v1.9.5 - Consolidate three RTC chip drivers (DS3231, BM8563, PCF85363) into one driver updating RTC as soon as possible after restart
- ESP8266SAM library from v1.0 to v1.0.1 - Removed command ``Sensor33`` and replaced by ``RtcNtpserver``
- BME68x-Sensor-API library from v3.5.9 to v4.4.7 - Remove support for Internet Explorer by allowing ECMAScript6 syntax using less JavaScript code bytes [#15280](https://github.com/arendst/Tasmota/issues/15280)
- SR04 driver to support US-100 - DS3231 I2C address define ``USE_RTC_ADDR`` into ``DS3231_ADDRESS``
- Mitsubishi HVAC temperature resolution [#13936](https://github.com/arendst/Tasmota/issues/13936) - Display of energy values in GUI use columns when define ``USE_ENERGY_COLUMN_GUI`` is enabled (default)
- Remove restriction of topic must differ from mqttclient [#14019](https://github.com/arendst/Tasmota/issues/14019) - ESP8266 Shrinked tasmota-minimal.bin by removing all commands except ``Upgrade``, ``Upload``, ``OtaUrl``, ``Seriallog``, ``Weblog`` and ``Restart``
- ESP32 Set stack size with ``#define SET_ESP32_STACK_SIZE``, added ``StackLowMark`` metrics - ESP32 Arduino core from v2.0.2.2 to v2.0.3
- ESP32 Berry stores compiled bytecode into IRAM, freeing space in heap [#14307](https://github.com/arendst/Tasmota/issues/14307) - ESP32 LVGL library from v8.1.0 to v8.2.0
- ESP32 NimBLE library from v1.3.3 to v1.3.6
- ESP32 update the internal Berry type system to sync with Skiars Berry repository. No expected impact on code, but .bec files need to be generated again [#14811](https://github.com/arendst/Tasmota/issues/14811)
### Fixed ### Fixed
- Intermittent exceptions and heap corruption due to PubSubClient library buffer overflow [#13700](https://github.com/arendst/Tasmota/issues/13700) - SSPM energy yesterday when zero
- EZOO2 sensor message format [#14000](https://github.com/arendst/Tasmota/issues/14000) - GPIO OptionE1 selection regression [#14821](https://github.com/arendst/Tasmota/issues/14821)
- DHT support negative temperatures on different hardware [#14173](https://github.com/arendst/Tasmota/issues/14173) - BL0939, BL0940 and BL0942 energy monitoring buffer miscompares resulting in wrong daily energy values regression from v9.5.0.8 [#14829](https://github.com/arendst/Tasmota/issues/14829)
- Hardware serial parity and stop bits support [#14212](https://github.com/arendst/Tasmota/issues/14212) - Wiegand 34-bit rfid reading and presentation [#14834](https://github.com/arendst/Tasmota/issues/14834)
- Edit file for SD card [#14229](https://github.com/arendst/Tasmota/issues/14229) - Orno WE517 power meter phase 2 current reactive [#14841](https://github.com/arendst/Tasmota/issues/14841)
- Scripter memory corruption [#14268](https://github.com/arendst/Tasmota/issues/14268) - NeoPool NPBit and NPRead/NPReadL output
- ESP32 Webcam exception during flashwrites - HX711 false readings by removing large deviations
- ESP32 LedPwmMode exception [#14073](https://github.com/arendst/Tasmota/issues/14073) - ESP32 save settings after OTA upload regression from v10.0.0.3
- ESP32 Compile error when I2S_Audio is enabled [#14095](https://github.com/arendst/Tasmota/issues/14095) - ESP32 PowerOnState [#15084](https://github.com/arendst/Tasmota/issues/15084)
- ESP32 Provide proper OTA_URL for tasmota32solo1 [#14202](https://github.com/arendst/Tasmota/issues/14202)
- ESP32 OneWire-Stickbreaker (DS18x20) library support for ESP32C3 and ESP32S2 [#14338](https://github.com/arendst/Tasmota/issues/14338)
### Removed ### Removed
- ESP32 consolidate odroidgo and core2 binaries into tasmota32-lvgl using Berry features

View File

@ -4,7 +4,7 @@
"ldscript": "esp32c3_out.ld" "ldscript": "esp32c3_out.ld"
}, },
"core": "esp32", "core": "esp32",
"extra_flags": "-DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3", "extra_flags": "-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3",
"f_cpu": "160000000L", "f_cpu": "160000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "dout", "flash_mode": "dout",

View File

@ -4,7 +4,7 @@
"ldscript": "esp32s2_out.ld" "ldscript": "esp32s2_out.ld"
}, },
"core": "esp32", "core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DESP32_4M -DESP32S2", "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S2",
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "dout", "flash_mode": "dout",

View File

@ -1,19 +1,22 @@
{ {
"build": { "build": {
"arduino":{ "arduino":{
"ldscript": "esp32s3_out.ld" "ldscript": "esp32s3_out.ld",
"memory_type": "qspi_qspi"
}, },
"core": "esp32", "core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DESP32_4M -DESP32S3", "extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_4M -DESP32S3",
"f_cpu": "240000000L", "f_cpu": "240000000L",
"f_flash": "80000000L", "f_flash": "80000000L",
"flash_mode": "dout", "flash_mode": "dio",
"mcu": "esp32s3", "mcu": "esp32s3",
"variant": "esp32s3", "variant": "esp32s3",
"partitions": "esp32_partition_app1856k_spiffs320k.csv" "partitions": "esp32_partition_app1856k_spiffs320k.csv"
}, },
"connectivity": [ "connectivity": [
"wifi" "wifi",
"bluetooth",
"ethernet"
], ],
"debug": { "debug": {
"openocd_target": "esp32s3.cfg" "openocd_target": "esp32s3.cfg"

38
boards/esp32s3_8M.json Normal file
View File

@ -0,0 +1,38 @@
{
"build": {
"arduino":{
"ldscript": "esp32s3_out.ld",
"memory_type": "qspi_qspi"
},
"core": "esp32",
"extra_flags": "-DBOARD_HAS_PSRAM -DARDUINO_USB_MODE=0 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DESP32_8M -DESP32S3",
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "dio",
"mcu": "esp32s3",
"variant": "esp32s3",
"partitions": "esp32_partition_app2944k_spiffs2M.csv"
},
"connectivity": [
"wifi",
"bluetooth",
"ethernet"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"espidf",
"arduino"
],
"name": "Espressif Generic ESP32-S3 8M Flash, Tasmota 2944k Code/OTA, 2112k FS",
"upload": {
"flash_size": "8MB",
"maximum_ram_size": 327680,
"maximum_size": 8388608,
"require_upload_port": true,
"speed": 460800
},
"url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/esp32s3/",
"vendor": "Espressif"
}

View File

@ -14,12 +14,16 @@ TasmotaSerial KEYWORD1
####################################### #######################################
begin KEYWORD2 begin KEYWORD2
end KEYWORD2
hardwareSerial KEYWORD2 hardwareSerial KEYWORD2
read KEYWORD2 peek KEYWORD2
write KEYWORD2 write KEYWORD2
read KEYWORD2
available KEYWORD2 available KEYWORD2
flush KEYWORD2 flush KEYWORD2
peek KEYWORD2 rxRead KEYWORD2
getLoopReadMetric KEYWORD2
getUart KEYWORD2
####################################### #######################################
# Constants (LITERAL1) # Constants (LITERAL1)

View File

@ -1,6 +1,6 @@
{ {
"name": "TasmotaSerial", "name": "TasmotaSerial",
"version": "3.4.0", "version": "3.5.0",
"keywords": [ "keywords": [
"serial", "io", "TasmotaSerial" "serial", "io", "TasmotaSerial"
], ],

View File

@ -1,5 +1,5 @@
name=TasmotaSerial name=TasmotaSerial
version=3.4.0 version=3.5.0
author=Theo Arends author=Theo Arends
maintainer=Theo Arends <theo@arends.com> maintainer=Theo Arends <theo@arends.com>
sentence=Implementation of software serial with hardware serial fallback for ESP8266 and ESP32. sentence=Implementation of software serial with hardware serial fallback for ESP8266 and ESP32.

View File

@ -40,7 +40,7 @@ TasmotaSerial *tms_obj_list[16];
#include "driver/uart.h" #include "driver/uart.h"
static int tasmota_serial_index = SOC_UART_NUM -1; // Available UART static uint32_t tasmota_serial_uart_bitmap = 0; // Assigned UARTs
#endif // ESP32 #endif // ESP32
@ -87,13 +87,16 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal
if ((receive_pin >= 0) && !GPIO_IS_VALID_GPIO(receive_pin)) { return; } if ((receive_pin >= 0) && !GPIO_IS_VALID_GPIO(receive_pin)) { return; }
if ((transmit_pin >= 0) && !GPIO_IS_VALID_OUTPUT_GPIO(transmit_pin)) { return; } if ((transmit_pin >= 0) && !GPIO_IS_VALID_OUTPUT_GPIO(transmit_pin)) { return; }
m_hardserial = true; m_hardserial = true;
TSerial = nullptr;
#endif // ESP32 #endif // ESP32
m_valid = true; m_valid = true;
} }
TasmotaSerial::~TasmotaSerial(void) { void TasmotaSerial::end(bool turnOffDebug) {
#ifdef ESP8266 #ifdef ESP8266
if (!m_hardserial) { if (m_hardserial) {
Serial.end();
} else {
if (m_rx_pin > -1) { if (m_rx_pin > -1) {
detachInterrupt(m_rx_pin); detachInterrupt(m_rx_pin);
tms_obj_list[m_rx_pin] = NULL; tms_obj_list[m_rx_pin] = NULL;
@ -105,15 +108,34 @@ TasmotaSerial::~TasmotaSerial(void) {
#endif // ESP8266 #endif // ESP8266
#ifdef ESP32 #ifdef ESP32
TSerial->end(); // Serial.printf("TSR: Freeing UART%d\n", m_uart);
tasmota_serial_index++; // This only works if no more uarts are requested otherwise will need a global used_uart log
TSerial->end(turnOffDebug);
bitClear(tasmota_serial_uart_bitmap, m_uart);
#endif // ESP32 #endif // ESP32
} }
TasmotaSerial::~TasmotaSerial(void) {
end();
}
bool TasmotaSerial::isValidGPIOpin(int pin) { bool TasmotaSerial::isValidGPIOpin(int pin) {
return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15); return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15);
} }
#ifdef ESP32
bool TasmotaSerial::freeUart(void) {
for (uint32_t i = SOC_UART_NUM -1; i >= 0; i--) {
if (0 == bitRead(tasmota_serial_uart_bitmap, i)) {
m_uart = i;
bitSet(tasmota_serial_uart_bitmap, m_uart);
return true;
}
}
return false;
}
#endif
bool TasmotaSerial::begin(uint32_t speed, uint32_t config) { bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
if (!m_valid) { return false; } if (!m_valid) { return false; }
@ -129,41 +151,42 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
} }
#endif // ESP8266 #endif // ESP8266
#ifdef ESP32 #ifdef ESP32
if (tasmota_serial_index >= 0) { // We prefer UART1 and UART2 and keep UART0 for debugging if (TSerial == nullptr) { // Allow for dynamic change in baudrate or config
m_uart = tasmota_serial_index; if (freeUart()) { // We prefer UART1 and UART2 and keep UART0 for debugging
tasmota_serial_index--; if (0 == m_uart) {
if (0 == m_uart) { Serial.flush();
Serial.flush(); Serial.end();
Serial.end(); delay(10); // Allow time to cleanup queues - if not used hangs ESP32
delay(10); // Allow time to cleanup queues - if not used hangs ESP32 TSerial = &Serial;
TSerial = &Serial; } else {
TSerial = new HardwareSerial(m_uart);
}
if (serial_buffer_size > 256) { // RX Buffer can't be resized when Serial is already running (HardwareSerial.cpp)
TSerial->setRxBufferSize(serial_buffer_size);
}
} else { } else {
TSerial = new HardwareSerial(m_uart); m_valid = false;
} return m_valid; // As we currently only support hardware serial on ESP32 it's safe to exit here
if (serial_buffer_size > 256) { // RX Buffer can't be resized when Serial is already running (HardwareSerial.cpp)
TSerial->setRxBufferSize(serial_buffer_size);
}
TSerial->begin(speed, config, m_rx_pin, m_tx_pin);
// For low bit rate, below 9600, set the Full RX threshold at 10 bytes instead of the default 120
if (speed <= 9600) {
// At 9600, 10 chars are ~10ms
uart_set_rx_full_threshold(m_uart, 10);
} else if (speed < 115200) {
// At 19200, 120 chars are ~60ms
// At 76800, 120 chars are ~15ms
uart_set_rx_full_threshold(m_uart, 120);
} else {
// At 115200, 256 chars are ~20ms
// Zigbee requires to keep frames together, i.e. 256 bytes max
uart_set_rx_full_threshold(m_uart, 256);
}
// For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10
if (speed < 115200) {
// At 76800 the timeout is ~1ms
uart_set_rx_timeout(m_uart, 6);
} }
}
TSerial->begin(speed, config, m_rx_pin, m_tx_pin);
// For low bit rate, below 9600, set the Full RX threshold at 10 bytes instead of the default 120
if (speed <= 9600) {
// At 9600, 10 chars are ~10ms
uart_set_rx_full_threshold(m_uart, 10);
} else if (speed < 115200) {
// At 19200, 120 chars are ~60ms
// At 76800, 120 chars are ~15ms
uart_set_rx_full_threshold(m_uart, 120);
} else { } else {
m_valid = false; // At 115200, 256 chars are ~20ms
// Zigbee requires to keep frames together, i.e. 256 bytes max
uart_set_rx_full_threshold(m_uart, 256);
}
// For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10
if (speed < 115200) {
// At 76800 the timeout is ~1ms
uart_set_rx_timeout(m_uart, 6);
} }
// Serial.printf("TSR: Using UART%d\n", m_uart); // Serial.printf("TSR: Using UART%d\n", m_uart);
#endif // ESP32 #endif // ESP32

View File

@ -41,6 +41,7 @@ class TasmotaSerial : public Stream {
virtual ~TasmotaSerial(); virtual ~TasmotaSerial();
bool begin(uint32_t speed = TM_SERIAL_BAUDRATE, uint32_t config = SERIAL_8N1); bool begin(uint32_t speed = TM_SERIAL_BAUDRATE, uint32_t config = SERIAL_8N1);
void end(bool turnOffDebug = true);
bool hardwareSerial(void); bool hardwareSerial(void);
int peek(void); int peek(void);
@ -53,15 +54,18 @@ class TasmotaSerial : public Stream {
void rxRead(void); void rxRead(void);
uint32_t getLoopReadMetric(void) const { return m_bit_follow_metric; } uint32_t getLoopReadMetric(void) const { return m_bit_follow_metric; }
#ifdef ESP32 #ifdef ESP32
uint32_t getUart(void) const { return m_uart; } uint32_t getUart(void) const { return m_uart; }
#endif #endif
bool isValid() { return m_valid; }
using Print::write; using Print::write;
private: private:
bool isValidGPIOpin(int pin); bool isValidGPIOpin(int pin);
#ifdef ESP32
bool freeUart(void);
#endif
size_t txWrite(uint8_t byte); size_t txWrite(uint8_t byte);
// Member variables // Member variables

View File

@ -19,9 +19,6 @@
*/ */
#include "AudioFileSourceFS.h" #include "AudioFileSourceFS.h"
#ifdef ESP32
#include "SPIFFS.h"
#endif
AudioFileSourceFS::AudioFileSourceFS(FS &fs, const char *filename) AudioFileSourceFS::AudioFileSourceFS(FS &fs, const char *filename)
{ {

View File

@ -18,8 +18,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _AUDIOFILESOURCESPIFFS_H #ifndef _AUDIOFILESOURCELITTLEFS_H
#define _AUDIOFILESOURCESPIFFS_H #define _AUDIOFILESOURCELITTLEFS_H
#include <Arduino.h> #include <Arduino.h>
#include <LittleFS.h> #include <LittleFS.h>

View File

@ -1,40 +0,0 @@
/*
AudioFileSourceFS
Input Arduion "file" to be used by AudioGenerator
Copyright (C) 2017 Earle F. Philhower, III
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _AUDIOFILESOURCESPIFFS_H
#define _AUDIOFILESOURCESPIFFS_H
#include <Arduino.h>
#include <FS.h>
#include "AudioFileSource.h"
#include "AudioFileSourceFS.h"
class AudioFileSourceSPIFFS : public AudioFileSourceFS
{
public:
AudioFileSourceSPIFFS() : AudioFileSourceFS(SPIFFS) { };
AudioFileSourceSPIFFS(const char *filename) : AudioFileSourceFS(SPIFFS, filename) {};
// Others are inherited from base
};
#endif

View File

@ -1,113 +0,0 @@
/*
AudioOutputSPIFFSWAV
Writes a WAV file to the SPIFFS filesystem
Copyright (C) 2017 Earle F. Philhower, III
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Arduino.h>
#include <FS.h>
#ifdef ESP32
#include "SPIFFS.h"
#endif
#include "AudioOutputSPIFFSWAV.h"
static const uint8_t wavHeaderTemplate[] PROGMEM = { // Hardcoded simple WAV header with 0xffffffff lengths all around
0x52, 0x49, 0x46, 0x46, 0xff, 0xff, 0xff, 0xff, 0x57, 0x41, 0x56, 0x45,
0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x22, 0x56, 0x00, 0x00, 0x88, 0x58, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
0x64, 0x61, 0x74, 0x61, 0xff, 0xff, 0xff, 0xff };
void AudioOutputSPIFFSWAV::SetFilename(const char *name)
{
if (filename) free(filename);
filename = strdup(name);
}
bool AudioOutputSPIFFSWAV::begin()
{
uint8_t wavHeader[sizeof(wavHeaderTemplate)];
memset(wavHeader, 0, sizeof(wavHeader));
if (f) return false; // Already open!
SPIFFS.remove(filename);
f = SPIFFS.open(filename, "w+");
if (!f) return false;
// We'll fix the header up when we close the file
f.write(wavHeader, sizeof(wavHeader));
return true;
}
bool AudioOutputSPIFFSWAV::ConsumeSample(int16_t sample[2])
{
for (int i=0; i<channels; i++) {
if (bps == 8) {
uint8_t l = sample[i] & 0xff;
f.write(&l, sizeof(l));
} else {
uint8_t l = sample[i] & 0xff;
uint8_t h = (sample[i] >> 8) & 0xff;
f.write(&l, sizeof(l));
f.write(&h, sizeof(h));
}
}
return true;
}
bool AudioOutputSPIFFSWAV::stop()
{
uint8_t wavHeader[sizeof(wavHeaderTemplate)];
memcpy_P(wavHeader, wavHeaderTemplate, sizeof(wavHeaderTemplate));
int chunksize = f.size() - 8;
wavHeader[4] = chunksize & 0xff;
wavHeader[5] = (chunksize>>8)&0xff;
wavHeader[6] = (chunksize>>16)&0xff;
wavHeader[7] = (chunksize>>24)&0xff;
wavHeader[22] = channels & 0xff;
wavHeader[23] = 0;
wavHeader[24] = hertz & 0xff;
wavHeader[25] = (hertz >> 8) & 0xff;
wavHeader[26] = (hertz >> 16) & 0xff;
wavHeader[27] = (hertz >> 24) & 0xff;
int byteRate = hertz * bps * channels / 8;
wavHeader[28] = byteRate & 0xff;
wavHeader[29] = (byteRate >> 8) & 0xff;
wavHeader[30] = (byteRate >> 16) & 0xff;
wavHeader[31] = (byteRate >> 24) & 0xff;
wavHeader[32] = channels * bps / 8;
wavHeader[33] = 0;
wavHeader[34] = bps;
wavHeader[35] = 0;
int datasize = f.size() - sizeof(wavHeader);
wavHeader[40] = datasize & 0xff;
wavHeader[41] = (datasize>>8)&0xff;
wavHeader[42] = (datasize>>16)&0xff;
wavHeader[43] = (datasize>>24)&0xff;
// Write real header out
f.seek(0, SeekSet);
f.write(wavHeader, sizeof(wavHeader));
f.close();
return true;
}

View File

@ -1,45 +0,0 @@
/*
AudioOutputSPIFFSWAV
Writes a WAV file to the SPIFFS filesystem
Copyright (C) 2017 Earle F. Philhower, III
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _AUDIOOUTPUTSPIFFSWAV_H
#define _AUDIOOUTPUTSPIFFSWAV_H
#include <Arduino.h>
#include <FS.h>
#include "AudioOutput.h"
class AudioOutputSPIFFSWAV : public AudioOutput
{
public:
AudioOutputSPIFFSWAV() { filename = NULL; };
~AudioOutputSPIFFSWAV() { free(filename); };
virtual bool begin() override;
virtual bool ConsumeSample(int16_t sample[2]) override;
virtual bool stop() override;
void SetFilename(const char *name);
private:
File f;
char *filename;
};
#endif

View File

@ -1,2 +1,21 @@
Attention when updating library. Changes in lib needed!! See Change in file `lib/lib_audio/ESP8266Audio/src/AudioOutputULP.cpp`
https://github.com/arendst/Tasmota/commit/feb08bcbc9a3e63c9f190fa1f227619985c96459 ```
from
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
to
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
```
remove in file `lib/lib_audio/ESP8266Audio/src/AudioFileSourceFS.cpp`
```
#ifdef ESP32
#include "SPIFFS.h"
#endif
```
Files to delete:
```
lib/lib_audio/ESP8266Audio/src/AudioFileSourceSPIFFS.h
lib/lib_audio/ESP8266Audio/src/AudioOutputSPIFFSWAV.cpp
lib/lib_audio/ESP8266Audio/src/AudioOutputSPIFFSWAV.h
```

View File

@ -10,8 +10,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.8.1 Now Available ## v2.8.2 Now Available
Version 2.8.1 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.8.2 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

@ -11,8 +11,8 @@
Diese Programmbibliothek ermöglicht das **Senden _und_ Empfangen** von Infrarotsignalen mit [ESP8266](https://github.com/esp8266/Arduino)- und Diese Programmbibliothek ermöglicht das **Senden _und_ Empfangen** von Infrarotsignalen mit [ESP8266](https://github.com/esp8266/Arduino)- und
[ESP32](https://github.com/espressif/arduino-esp32)-Mikrocontrollern mithilfe des [Arduino-Frameworks](https://www.arduino.cc/) und handelsüblichen 940nm Infrarot-LEDs undIR-Empfängermodulen, wie zum Beispiel TSOP{17,22,24,36,38,44,48}*-Demodulatoren. [ESP32](https://github.com/espressif/arduino-esp32)-Mikrocontrollern mithilfe des [Arduino-Frameworks](https://www.arduino.cc/) und handelsüblichen 940nm Infrarot-LEDs undIR-Empfängermodulen, wie zum Beispiel TSOP{17,22,24,36,38,44,48}*-Demodulatoren.
## v2.8.1 jetzt verfügbar ## v2.8.2 jetzt verfügbar
Version 2.8.1 der Bibliothek ist nun [verfügbar](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Die [Versionshinweise](ReleaseNotes.md) enthalten alle wichtigen Neuerungen. Version 2.8.2 der Bibliothek ist nun [verfügbar](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Die [Versionshinweise](ReleaseNotes.md) enthalten alle wichtigen Neuerungen.
#### Hinweis für Nutzer von Versionen vor v2.0 #### Hinweis für Nutzer von Versionen vor v2.0
Die Benutzung der Bibliothek hat sich mit Version 2.0 leicht geändert. Einige Anpassungen im aufrufenden Code werden nötig sein, um mit Version ab 2.0 korrekt zu funktionieren. Mehr zu den Anpassungen finden sich auf unserer [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0)-Seite. Die Benutzung der Bibliothek hat sich mit Version 2.0 leicht geändert. Einige Anpassungen im aufrufenden Code werden nötig sein, um mit Version ab 2.0 korrekt zu funktionieren. Mehr zu den Anpassungen finden sich auf unserer [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0)-Seite.

View File

@ -10,8 +10,8 @@
Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole Cette librairie vous permetra de **recevoir et d'envoyer des signaux** infrarouge sur le protocole [ESP8266](https://github.com/esp8266/Arduino) ou sur le protocole
[ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc. [ESP32](https://github.com/espressif/arduino-esp32) en utilisant le [Arduino framework](https://www.arduino.cc/) qui utilise la norme 940nm IR LEDs et le module basique de reception d'onde IR. Exemple : TSOP{17,22,24,36,38,44,48}* modules etc.
## v2.8.1 disponible ## v2.8.2 disponible
Version 2.8.1 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants. Version 2.8.2 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants.
#### mise à jour depuis pre-v2.0 #### mise à jour depuis pre-v2.0
L'utilisation de la librairie à un peu changer depuis la version in v2.0. Si vous voulez l'utiliser vous devrez changer votre utilisation aussi. Vous pouvez vous renseigner sur les précondition d'utilisation ici : [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page. L'utilisation de la librairie à un peu changer depuis la version in v2.0. Si vous voulez l'utiliser vous devrez changer votre utilisation aussi. Vous pouvez vous renseigner sur les précondition d'utilisation ici : [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.

View File

@ -1,5 +1,38 @@
# Release Notes # Release Notes
## _v2.8.2 (20220314)_
**[Bug Fixes]**
- ESP32-C3: Fix reboot/crashes on ESP32-C3s when receiving. (#1768 #1751)
**[Features]**
- HITACHI_AC296: Add `IRac` class support & tests. (#1776 #1758 #1757)
- Support for Hitachi RAS-70YHA3 (remote RAR-3U3) (#1758 #1757)
- LG: Add Swing Toggle support for Model `LG6711A20083V` (#1771 #1770)
- IRMQTTServer: add `MQTT_SERVER_AUTODETECT_ENABLE` via mqtt mDNS (#1769)
- Experimental basic support for Kelon 168 bit / 21 byte protocol. (#1747 #1745 #1744)
- MitsubishiAC: Tweak repeat gap timing. (#1760 #1759)
- Gree YAP0F8 (Detected as Kelvinator) vertical position set support (#1756)
- Make KELON (48 bit) protocol decoding stricter. (#1746 #1744)
- IRMQTTServer V1.6.1 (#1740 #1739 #1729)
- HITACHI_AC264: Add minimal detailed support. (#1735 #1729)
- LG2: Improve Light toggle msg handling. (#1738 #1737)
- MIDEA: Add support for Quiet, Clean & Freeze Protect controls. (#1734 #1733)
- Add basic support for HITACHI_AC264 264bit protocol. (#1730 #1729)
- ESP32-C3: Work around for some C3 specific compiler issues again. (#1732 #1695)
**[Misc]**
- MIDEA: Update supported devices (#1774 #1773 #1716)
- Update devices supported by ELECTRA_AC (#1766 #1765)
- Improve documentation for `encodePioneer()` (#1761 #1749)
- Update (un)supported DAIKIN128 devices. (#1752)
- Refactor `decodeCOOLIX()` code & add another test case. (#1750 #1748)
- Simplify code based on state_t being initialised by default. (#1736 #1699)
- Add comments to help Teknopoint users. (#1731 #1728)
- Fix library version string calculation. (#1727 #1725)
- Confirm we can reproduce `TurnOnFujitsuAC.ino` via IRac/IRMQTTServer. (#1726 #1701)
## _v2.8.1 (20220101)_ ## _v2.8.1 (20220101)_
**[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: Fri 31 Dec 2021 21:49:00 +0000 ---> Last generated: Mon 14 Mar 2022 06:52:21 +0000 --->
# 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 |
@ -22,12 +22,13 @@
| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Tokio](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote | | Yes | | [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Tokio](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | AATOEMF17-12CHR1SW split-type RG51\|50/BGE Remote | | Yes |
| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | RAS-4M27YAV-E A/C<BR>RAS-M10YKV-E A/C<BR>RAS-M13YKV-E A/C<BR>WH-E1YE remote | | Yes | | [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | RAS-4M27YAV-E A/C<BR>RAS-M10YKV-E A/C<BR>RAS-M13YKV-E A/C<BR>WH-E1YE remote | | Yes |
| [Corona](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Corona.cpp) | **[Corona](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Corona.h)** | AR-01 remote<BR>CSH-N2211 A/C<BR>CSH-N2511 A/C<BR>CSH-N2811 A/C<BR>CSH-N4011 A/C | | Yes | | [Corona](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Corona.cpp) | **[Corona](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Corona.h)** | AR-01 remote<BR>CSH-N2211 A/C<BR>CSH-N2511 A/C<BR>CSH-N2811 A/C<BR>CSH-N4011 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 (DAIKIN160)<BR>ARC433** remote (DAIKIN)<BR>ARC433B69 remote (DAIKIN216)<BR>ARC466A33 remote (DAIKIN)<BR>ARC477A1 remote (DAIKIN2)<BR>ARC480A5 remote (DAIKIN152)<BR>ARC484A4 remote (DAIKIN216)<BR>BRC4C151 remote (DAIKIN176)<BR>BRC4C153 remote (DAIKIN176)<BR>BRC52B63 remote (DAIKIN128)<BR>DGS01 remote (DAIKIN64)<BR>FFN-C/FCN-F Series A/C (DAIKIN64)<BR>FFQ35B8V1B A/C (DAIKIN176)<BR>FTE12HV2S A/C<BR>FTQ60TV16U2 A/C (DAIKIN216)<BR>FTWX35AXV1 A/C (DAIKIN64)<BR>FTXB09AXVJU A/C (DAIKIN128)<BR>FTXB12AXVJU A/C (DAIKIN128)<BR>FTXM-M A/C (DAIKIN)<BR>FTXZ25NV1B A/C (DAIKIN2)<BR>FTXZ35NV1B A/C (DAIKIN2)<BR>FTXZ50NV1B A/C (DAIKIN2)<BR>M Series A/C (DAIKIN) | | 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 FTXB09AXVJU A/C (DAIKIN128)<BR>17 Series FTXB12AXVJU A/C (DAIKIN128)<BR>17 Series FTXB24AXVJU A/C (NOT SUPPORTED)<BR>ARC423A5 remote (DAIKIN160)<BR>ARC433** remote (DAIKIN)<BR>ARC433B69 remote (DAIKIN216)<BR>ARC466A33 remote (DAIKIN)<BR>ARC477A1 remote (DAIKIN2)<BR>ARC480A5 remote (DAIKIN152)<BR>ARC484A4 remote (DAIKIN216)<BR>BRC4C151 remote (DAIKIN176)<BR>BRC4C153 remote (DAIKIN176)<BR>BRC52B63 remote (DAIKIN128)<BR>DGS01 remote (DAIKIN64)<BR>FFN-C/FCN-F Series A/C (DAIKIN64)<BR>FFQ35B8V1B A/C (DAIKIN176)<BR>FTE12HV2S A/C<BR>FTQ60TV16U2 A/C (DAIKIN216)<BR>FTWX35AXV1 A/C (DAIKIN64)<BR>FTXM-M A/C (DAIKIN)<BR>FTXZ25NV1B A/C (DAIKIN2)<BR>FTXZ35NV1B A/C (DAIKIN2)<BR>FTXZ50NV1B A/C (DAIKIN2)<BR>M Series A/C (DAIKIN) | | Yes |
| [Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.cpp) | **[Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.h)** | PAC A95 | | Yes | | [Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.cpp) | **[Delonghi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Delonghi.h)** | PAC A95 | | Yes |
| [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Denon** | AVR-3801 A/V Receiver (probably) | | - | | [Denon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Denon.cpp) | **Denon** | AVR-3801 A/V Receiver (probably) | | - |
| [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 | | - |
| [Doshisha](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Doshisha.cpp) | **Doshisha** | CZ-S32D LED Light<BR>CZ-S38D LED Light<BR>CZ-S50D LED Light<BR>RCZ01 remote | | - | | [Doshisha](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Doshisha.cpp) | **Doshisha** | CZ-S32D LED Light<BR>CZ-S38D LED Light<BR>CZ-S50D LED Light<BR>RCZ01 remote | | - |
| [Ecoclim](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Ecoclim.cpp) | **[EcoClim](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Ecoclim.h)** | HYSFR-P348 remote<BR>ZC200DPO A/C | | Yes | | [Ecoclim](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Ecoclim.cpp) | **[EcoClim](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Ecoclim.h)** | HYSFR-P348 remote<BR>ZC200DPO A/C | | Yes |
| [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[AEG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | Chillflex Pro AXP26U338CW A/C | | 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 | | [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) | **[Centek](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | SCT-65Q09 A/C<BR>YKR-P/002E remote | | Yes | | [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[Centek](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | SCT-65Q09 A/C<BR>YKR-P/002E remote | | Yes |
| [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | Classic INV 17 / AXW12DCS A/C<BR>YKR-M/003E remote | | Yes | | [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | Classic INV 17 / AXW12DCS A/C<BR>YKR-M/003E remote | | Yes |
@ -52,15 +53,17 @@
| [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Daichi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | D-H A/C (HAIER_AC176) | | Yes | | [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Daichi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | D-H A/C (HAIER_AC176) | | 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 (HAIER_AC_YRW02)<BR>HSU07-HEA03 remote (HAIER_AC)<BR>V9014557 M47 8D remote (HAIER_AC176)<BR>YR-W02 remote (HAIER_AC_YRW02) | | 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 (HAIER_AC_YRW02)<BR>HSU07-HEA03 remote (HAIER_AC)<BR>V9014557 M47 8D remote (HAIER_AC176)<BR>YR-W02 remote (HAIER_AC_YRW02) | | Yes |
| [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Mabe](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | MMI18HDBWCA6MI8 A/C (HAIER_AC176)<BR>V12843 HJ200223 remote (HAIER_AC176) | | Yes | | [Haier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.cpp) | **[Mabe](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Haier.h)** | MMI18HDBWCA6MI8 A/C (HAIER_AC176)<BR>V12843 HJ200223 remote (HAIER_AC176) | | Yes |
| [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | KAZE-312KSDP A/C (HITACHI_AC1)<BR>LT0541-HTA remote (HITACHI_AC1)<BR>PC-LH3B (HITACHI_AC3)<BR>R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)<BR>RAR-8P2 remote (HITACHI_AC424)<BR>RAS-22NK A/C (HITACHI_AC344)<BR>RAS-35THA6 remote<BR>RAS-AJ25H A/C (HITACHI_AC424)<BR>RF11T1 remote (HITACHI_AC344)<BR>Series VI A/C (Circa 2007) (HITACHI_AC1) | | Yes | | [Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.cpp) | **[Hitachi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Hitachi.h)** | KAZE-312KSDP A/C (HITACHI_AC1)<BR>LT0541-HTA remote (HITACHI_AC1)<BR>PC-LH3B (HITACHI_AC3)<BR>R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)<BR>RAK-25NH5 A/C (HITACHI_AC264)<BR>RAR-2P2 remote (HITACHI_AC264)<BR>RAR-3U3 remote (HITACHI_AC296)<BR>RAR-8P2 remote (HITACHI_AC424)<BR>RAS-22NK A/C (HITACHI_AC344)<BR>RAS-35THA6 remote<BR>RAS-70YHA3 A/C (HITACHI_AC296)<BR>RAS-AJ25H A/C (HITACHI_AC424)<BR>RF11T1 remote (HITACHI_AC344)<BR>Series VI A/C (Circa 2007) (HITACHI_AC1) | | 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) | **JVC** | PTU94023B remote | | - | | [JVC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_JVC.cpp) | **JVC** | PTU94023B remote | | - |
| [Kelon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.cpp) | **[Kelon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.h)** | ON/OFF 9000-12000 | | Yes | | [Kelon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.cpp) | **[Hisense](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.h)** | AST-09UW4RVETG00A A/C (KELON168) | | Yes |
| [Kelon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.cpp) | **[Kelon](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelon.h)** | AST-09UW4RVETG00A A/C (KELON168)<BR>DG11R2-01 remote (KELON168)<BR>ON/OFF 9000-12000 (KELON) | | Yes |
| [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | YAP0F8 remote | | Yes |
| [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) | **[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 |
| [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | A5VEY A/C<BR>YB1FA remote | | Yes | | [Kelvinator](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.cpp) | **[Sharp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Kelvinator.h)** | A5VEY A/C<BR>YB1FA remote | | Yes |
| [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[General Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711AR2853M A/C Remote (LG)<BR>AG1BH09AW101 Split A/C (LG) | | Yes | | [LG](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.cpp) | **[General Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_LG.h)** | 6711AR2853M Remote (LG - GE6711AR2853M)<BR>AG1BH09AW101 A/C (LG - GE6711AR2853M) | | 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 (LG)<BR>A4UW30GFA2 A/C (LG2 - AKB74955603 & AKB73757604)<BR>AKB73315611 remote (LG2 - AKB74955603)<BR>AKB73757604 remote (LG2 - AKB73757604)<BR>AKB74395308 remote (LG2)<BR>AKB74955603 remote (LG2 - AKB74955603)<BR>AKB75215403 remote (LG2)<BR>AMNW09GSJA0 A/C (LG2 - AKB74955603)<BR>AMNW24GTPA1 A/C (LG2 - AKB73757604)<BR>MS05SQ NW0 A/C (LG2 - AKB74955603)<BR>S4-W12JA3AA A/C (LG2) | | 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 (LG - LG6711A20083V)<BR>A4UW30GFA2 A/C (LG2 - AKB74955603 & AKB73757604)<BR>AKB73315611 remote (LG2 - AKB74955603)<BR>AKB73757604 remote (LG2 - AKB73757604)<BR>AKB74395308 remote (LG2)<BR>AKB74955603 remote (LG2 - AKB74955603)<BR>AKB75215403 remote (LG2)<BR>AMNW09GSJA0 A/C (LG2 - AKB74955603)<BR>AMNW24GTPA1 A/C (LG2 - AKB73757604)<BR>MS05SQ NW0 A/C (LG2 - AKB74955603)<BR>S4-W12JA3AA A/C (LG2)<BR>TS-H122ERM1 remote (LG - LG6711A20083V) | | Yes |
| [Lasertag](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lasertag.cpp) | **Lasertag** | Phaser emitters | | - | | [Lasertag](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lasertag.cpp) | **Lasertag** | Phaser emitters | | - |
| [Lego](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lego.cpp) | **LEGO Power Functions** | IR Receiver | | - | | [Lego](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lego.cpp) | **LEGO Power Functions** | IR Receiver | | - |
| [Lutron](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lutron.cpp) | **Lutron** | MIR-ITFS remote<BR>MIR-ITFS-F remote<BR>MIR-ITFS-LF remote<BR>SP-HT remote | | - | | [Lutron](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Lutron.cpp) | **Lutron** | MIR-ITFS remote<BR>MIR-ITFS-F remote<BR>MIR-ITFS-LF remote<BR>SP-HT remote | | - |
@ -71,6 +74,7 @@
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Danby](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | DAC080BGUWDB (MIDEA)<BR>DAC100BGUWDB (MIDEA)<BR>DAC120BGUWDB (MIDEA)<BR>R09C/BCGE remote (MIDEA) | | Yes | | [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Danby](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | DAC080BGUWDB (MIDEA)<BR>DAC100BGUWDB (MIDEA)<BR>DAC120BGUWDB (MIDEA)<BR>R09C/BCGE remote (MIDEA) | | Yes |
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Kaysun](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | Casual CF A/C (MIDEA) | | Yes | | [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Kaysun](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | Casual CF A/C (MIDEA) | | 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 (MIDEA) | | 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 (MIDEA) | | Yes |
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Lennox](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | M22A indoor split A/C (MIDEA)<BR>M33A indoor split A/C (MIDEA)<BR>M33B indoor split A/C (MIDEA)<BR>MCFA indoor split A/C (MIDEA)<BR>MCFB indoor split A/C (MIDEA)<BR>MMDA indoor split A/C (MIDEA)<BR>MMDB indoor split A/C (MIDEA)<BR>MWMA indoor split A/C (MIDEA)<BR>MWMA009S4-3P A/C (MIDEA)<BR>MWMA012S4-3P A/C (MIDEA)<BR>MWMB indoor split A/C (MIDEA)<BR>RG57A6/BGEFU1 remote (MIDEA) | | Yes |
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | FS40-7AR Stand Fan (MIDEA24) | | Yes | | [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | FS40-7AR Stand Fan (MIDEA24) | | Yes |
| [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[MrCool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RG57A6/BGEFU1 remote (MIDEA) | | Yes | | [Midea](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.cpp) | **[MrCool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Midea.h)** | RG57A6/BGEFU1 remote (MIDEA) | | 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)** | RG66B6(B)/BGEFU1 remote (MIDEA)<BR>RUBO18GMFILCAD A/C (18K BTU) (MIDEA)<BR>RYBO12GMFILCAD A/C (12K BTU) (MIDEA)<BR>UB018GMFILCFHD A/C (12K BTU) (MIDEA)<BR>WS012GMFI22HLD A/C (12K BTU) (MIDEA)<BR>WS018GMFI22HLD A/C (12K BTU) (MIDEA) | | 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)** | RG66B6(B)/BGEFU1 remote (MIDEA)<BR>RUBO18GMFILCAD A/C (18K BTU) (MIDEA)<BR>RYBO12GMFILCAD A/C (12K BTU) (MIDEA)<BR>UB018GMFILCFHD A/C (12K BTU) (MIDEA)<BR>WS012GMFI22HLD A/C (12K BTU) (MIDEA)<BR>WS018GMFI22HLD A/C (12K BTU) (MIDEA) | | Yes |
@ -80,7 +84,7 @@
| [Mirage](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mirage.cpp) | **[Mirage](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mirage.h)** | VLU series A/C | KKG29AC1<BR>KKG9AC1 | Yes | | [Mirage](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mirage.cpp) | **[Mirage](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mirage.h)** | VLU series A/C | KKG29AC1<BR>KKG9AC1 | Yes |
| [Mirage](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mirage.cpp) | **[Tronitechnik](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mirage.h)** | KKG29A-C1 remote<BR>Reykir 9000 A/C | KKG29AC1<BR>KKG9AC1 | Yes | | [Mirage](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mirage.cpp) | **[Tronitechnik](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mirage.h)** | KKG29A-C1 remote<BR>Reykir 9000 A/C | KKG29AC1<BR>KKG9AC1 | 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 (MITSUBISHI2)<BR>KM14A 0179213 remote<BR>MS-GK24VA A/C<BR>TV (MITSUBISHI) | | 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 (MITSUBISHI2)<BR>KM14A 0179213 remote<BR>MS-GK24VA A/C<BR>TV (MITSUBISHI) | | Yes |
| [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | 001CP T7WE10714 remote (MITSUBISHI136)<BR>KPOA remote (MITSUBISHI112)<BR>MLZ-RX5017AS A/C (MITSUBISHI_AC)<BR>MSH-A24WV A/C (MITSUBISHI112)<BR>MSZ-FHnnVE A/C (MITSUBISHI_AC)<BR>MSZ-GV2519 A/C (MITSUBISHI_AC)<BR>MSZ-SF25VE3 A/C (MITSUBISHI_AC)<BR>MSZ-ZW4017S A/C (MITSUBISHI_AC)<BR>MUH-A24WV A/C (MITSUBISHI112)<BR>PEAD-RP71JAA Ducted A/C (MITSUBISHI136)<BR>RH151/M21ED6426 remote (MITSUBISHI_AC)<BR>SG153/M21EDF426 remote (MITSUBISHI_AC)<BR>SG15D remote (MITSUBISHI_AC) | | Yes | | [Mitsubishi](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.cpp) | **[Mitsubishi Electric](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Mitsubishi.h)** | 001CP T7WE10714 remote (MITSUBISHI136)<BR>KPOA remote (MITSUBISHI112)<BR>MLZ-RX5017AS A/C (MITSUBISHI_AC)<BR>MSH-A24WV A/C (MITSUBISHI112)<BR>MSZ-FHnnVE A/C (MITSUBISHI_AC)<BR>MSZ-GV2519 A/C (MITSUBISHI_AC)<BR>MSZ-SF25VE3 A/C (MITSUBISHI_AC)<BR>MSZ-ZW4017S A/C (MITSUBISHI_AC)<BR>MUH-A24WV A/C (MITSUBISHI112)<BR>PEAD-RP71JAA Ducted A/C (MITSUBISHI136)<BR>RH151 remote (MITSUBISHI_AC)<BR>RH151/M21ED6426 remote (MITSUBISHI_AC)<BR>SG153/M21EDF426 remote (MITSUBISHI_AC)<BR>SG15D remote (MITSUBISHI_AC) | | 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 (88 bit)<BR>RLA502A700B remote (152 bit)<BR>SRKxxZJ-S A/C (88 bit)<BR>SRKxxZM-S A/C (152 bit)<BR>SRKxxZMXA-S A/C (152 bit) | | 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 (88 bit)<BR>RLA502A700B remote (152 bit)<BR>SRKxxZJ-S A/C (88 bit)<BR>SRKxxZM-S A/C (152 bit)<BR>SRKxxZMXA-S A/C (152 bit) | | Yes |
| [Multibrackets](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Multibrackets.cpp) | **Multibrackets** | Motorized Swing mount large - 4500 | | - | | [Multibrackets](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Multibrackets.cpp) | **Multibrackets** | Motorized Swing mount large - 4500 | | - |
| [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Aloka](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | SleepyLights LED Lamp | | - | | [NEC](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.cpp) | **[Aloka](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_NEC.h)** | SleepyLights LED Lamp | | - |
@ -114,7 +118,7 @@
| [Tcl](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.cpp) | **[Teknopoint](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.h)** | Allegro SSA-09H A/C (GZ055BE1)<BR>GZ-055B-E1 remote (GZ055BE1) | GZ055BE1<BR>TAC09CHSD | Yes | | [Tcl](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.cpp) | **[Teknopoint](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Tcl.h)** | Allegro SSA-09H A/C (GZ055BE1)<BR>GZ-055B-E1 remote (GZ055BE1) | GZ055BE1<BR>TAC09CHSD | Yes |
| [Technibel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Technibel.cpp) | **[Technibel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Technibel.h)** | IRO PLUS | | Yes | | [Technibel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Technibel.cpp) | **[Technibel](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Technibel.h)** | IRO PLUS | | Yes |
| [Teco](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.cpp) | **[Alaska](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.h)** | SAC9010QC A/C<BR>SAC9010QC remote | | Yes | | [Teco](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.cpp) | **[Alaska](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teco.h)** | SAC9010QC A/C<BR>SAC9010QC remote | | Yes |
| [Teknopoint](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teknopoint.cpp) | **Teknopoint** | Allegro SSA-09H A/C<BR>GZ-055B-E1 remote | | - | | [Teknopoint](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Teknopoint.cpp) | **Teknopoint** | Allegro SSA-09H A/C<BR>GZ-055B-E1 remote<BR>GZ01-BEJ0-000 remote | | - |
| [Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.cpp) | **[Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.h)** | 42NQV025M2 / 38NYV025M2 A/C<BR>42NQV035M2 / 38NYV035M2 A/C<BR>42NQV050M2 / 38NYV050M2 A/C<BR>42NQV060M2 / 38NYV060M2 A/C | | Yes | | [Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.cpp) | **[Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.h)** | 42NQV025M2 / 38NYV025M2 A/C<BR>42NQV035M2 / 38NYV035M2 A/C<BR>42NQV050M2 / 38NYV050M2 A/C<BR>42NQV060M2 / 38NYV060M2 A/C | | Yes |
| [Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.h)** | Akita EVO II<BR>RAS 18SKP-ES<BR>RAS-2558V A/C<BR>RAS-25SKVP2-ND A/C<BR>RAS-B13N3KV2<BR>RAS-B13N3KVP-E<BR>WC-L03SE<BR>WH-TA01JE remote<BR>WH-TA04NE<BR>WH-UB03NJ remote | | Yes | | [Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.cpp) | **[Toshiba](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Toshiba.h)** | Akita EVO II<BR>RAS 18SKP-ES<BR>RAS-2558V A/C<BR>RAS-25SKVP2-ND A/C<BR>RAS-B13N3KV2<BR>RAS-B13N3KVP-E<BR>WC-L03SE<BR>WH-TA01JE remote<BR>WH-TA04NE<BR>WH-UB03NJ remote | | Yes |
| [Transcold](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Transcold.cpp) | **[Transcold](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Transcold.h)** | M1-F-NO-6 A/C | | Yes | | [Transcold](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Transcold.cpp) | **[Transcold](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Transcold.h)** | M1-F-NO-6 A/C | | Yes |
@ -179,12 +183,15 @@
- HITACHI_AC - HITACHI_AC
- HITACHI_AC1 - HITACHI_AC1
- HITACHI_AC2 - HITACHI_AC2
- HITACHI_AC264
- HITACHI_AC296
- HITACHI_AC3 - HITACHI_AC3
- HITACHI_AC344 - HITACHI_AC344
- HITACHI_AC424 - HITACHI_AC424
- INAX - INAX
- JVC - JVC
- KELON - KELON
- KELON168
- KELVINATOR - KELVINATOR
- LASERTAG - LASERTAG
- LEGOPF - LEGOPF

View File

@ -57,7 +57,12 @@
// The GPIO an IR detector/demodulator is connected to. Recommended: 14 (D5) // The GPIO an IR detector/demodulator is connected to. Recommended: 14 (D5)
// Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts.
// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot.
#ifdef ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop.
#else // ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 14; const uint16_t kRecvPin = 14;
#endif // ARDUINO_ESP32C3_DEV
// GPIO to use to control the IR LED circuit. Recommended: 4 (D2). // GPIO to use to control the IR LED circuit. Recommended: 4 (D2).
const uint16_t kIrLedPin = 4; const uint16_t kIrLedPin = 4;

View File

@ -169,6 +169,11 @@ const uint32_t kMqttReconnectTime = 5000; // Delay(ms) between reconnect tries.
// In theory, you shouldn't need this as you can always clean up by hand, hence // In theory, you shouldn't need this as you can always clean up by hand, hence
// it is disabled by default. Note: `false` saves ~1.2k. // it is disabled by default. Note: `false` saves ~1.2k.
#define MQTT_CLEAR_ENABLE false #define MQTT_CLEAR_ENABLE false
#ifndef MQTT_SERVER_AUTODETECT_ENABLE
// Whether or not MQTT Server IP is detected through mDNS
#define MQTT_SERVER_AUTODETECT_ENABLE true
#endif // MQTT_SERVER_AUTODETECT_ENABLE
#endif // MQTT_ENABLE #endif // MQTT_ENABLE
// ------------------------ IR Capture Settings -------------------------------- // ------------------------ IR Capture Settings --------------------------------
@ -285,7 +290,7 @@ const uint16_t kJsonAcStateMaxSize = 1024; // Bytes
// ----------------- End of User Configuration Section ------------------------- // ----------------- End of User Configuration Section -------------------------
// Constants // Constants
#define _MY_VERSION_ "v1.6.0" #define _MY_VERSION_ "v1.7.0"
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

@ -24,6 +24,10 @@
* ## Before First Boot (i.e. Compile time) * ## Before First Boot (i.e. Compile time)
* - Disable MQTT if desired. (see '#define MQTT_ENABLE' in IRMQTTServer.h). * - Disable MQTT if desired. (see '#define MQTT_ENABLE' in IRMQTTServer.h).
* *
* - The MQTT server IP is detected automatically through mDNS (aka avahi,
* bonjour, zeroconf) if the server advertises _mqtt._tcp. Disable this if
* desired (see '#define MQTT_SERVER_AUTODETECT_ENABLE' in IRMQTTServer.h).
*
* - Site specific settings: * - Site specific settings:
* o Search for 'CHANGE_ME' in IRMQTTServer.h for the things you probably * o Search for 'CHANGE_ME' in IRMQTTServer.h for the things you probably
* need to change for your particular situation. * need to change for your particular situation.
@ -1973,6 +1977,29 @@ void handleNotFound(void) {
server.send(404, "text/plain", message); server.send(404, "text/plain", message);
} }
#if (MQTT_ENABLE && MQTT_SERVER_AUTODETECT_ENABLE)
void mqtt_detect_server(void) {
debug("Looking for the MQTT server...");
int nrOfServices = MDNS.queryService("mqtt", "tcp");
if (nrOfServices == 0) {
debug("MQTT server not found");
return;
}
debug(("Number of MQTT servers found: " + String(nrOfServices)).c_str());
for (int i = 0; i < nrOfServices; i=i+1) {
debug(("Hostname: " + MDNS.hostname(i)).c_str());
debug(("IP address: " + MDNS.IP(i).toString()).c_str());
debug(("Port: " + String(MDNS.port(i))).c_str());
}
strncpy(MqttServer, MDNS.IP(0).toString().c_str(), kHostnameLength);
strncpy(MqttPort, String(MDNS.port(0)).c_str(), kPortLength);
debug(("First one selected: " + String(MqttServer) + ":" +
String(MqttPort)).c_str());
}
#endif // (MQTT_ENABLE && MQTT_SERVER_AUTODETECT_ENABLE))
void setup_wifi(void) { void setup_wifi(void) {
delay(10); delay(10);
loadConfigFile(); loadConfigFile();
@ -2000,6 +2027,12 @@ void setup_wifi(void) {
WiFiManagerParameter custom_mqtt_text( WiFiManagerParameter custom_mqtt_text(
"<br><br><center>MQTT Broker details</center>"); "<br><br><center>MQTT Broker details</center>");
wifiManager.addParameter(&custom_mqtt_text); wifiManager.addParameter(&custom_mqtt_text);
#if MQTT_SERVER_AUTODETECT_ENABLE
WiFiManagerParameter custom_mqtt_server_text(
"<br><left>NOTE: if _mqtt._tcp mDNS service is found, it will be "
"used instead of the mqtt server:port below</left><br><br>");
wifiManager.addParameter(&custom_mqtt_server_text);
#endif // MQTT_SERVER_AUTODETECT_ENABLE
WiFiManagerParameter custom_mqtt_server( WiFiManagerParameter custom_mqtt_server(
kMqttServerKey, "mqtt server", MqttServer, kHostnameLength); kMqttServerKey, "mqtt server", MqttServer, kHostnameLength);
wifiManager.addParameter(&custom_mqtt_server); wifiManager.addParameter(&custom_mqtt_server);
@ -2196,6 +2229,9 @@ void setup(void) {
// Finish setup of the mqtt clent object. // Finish setup of the mqtt clent object.
if (!mqtt_client.setBufferSize(kMqttBufferSize)) if (!mqtt_client.setBufferSize(kMqttBufferSize))
debug("Can't fully allocate MQTT buffer! Try a smaller value."); debug("Can't fully allocate MQTT buffer! Try a smaller value.");
#if MQTT_SERVER_AUTODETECT_ENABLE
mqtt_detect_server();
#endif // MQTT_SERVER_AUTODETECT_ENABLE
mqtt_client.setServer(MqttServer, atoi(MqttPort)); mqtt_client.setServer(MqttServer, atoi(MqttPort));
mqtt_client.setCallback(mqttCallback); mqtt_client.setCallback(mqttCallback);
// Set various variables // Set various variables
@ -2308,6 +2344,10 @@ bool reconnect(void) {
uint16_t tries = 1; uint16_t tries = 1;
while (!mqtt_client.connected() && tries <= 3) { while (!mqtt_client.connected() && tries <= 3) {
int connected = false; int connected = false;
#if MQTT_SERVER_AUTODETECT_ENABLE
mqtt_detect_server();
mqtt_client.setServer(MqttServer, atoi(MqttPort));
#endif // MQTT_SERVER_AUTODETECT_ENABLE
// Attempt to connect // Attempt to connect
debug(("Attempting MQTT connection to " + String(MqttServer) + ":" + debug(("Attempting MQTT connection to " + String(MqttServer) + ":" +
String(MqttPort) + "... ").c_str()); String(MqttPort) + "... ").c_str());
@ -2863,7 +2903,8 @@ bool sendInt(const String topic, const int32_t num, const bool retain) {
bool sendBool(const String topic, const bool on, const bool retain) { bool sendBool(const String topic, const bool on, const bool retain) {
#if MQTT_ENABLE #if MQTT_ENABLE
mqttSentCounter++; mqttSentCounter++;
return mqtt_client.publish(topic.c_str(), (on ? "on" : "off"), retain); return mqtt_client.publish(topic.c_str(), (on ? D_STR_ON : D_STR_OFF),
retain);
#else // MQTT_ENABLE #else // MQTT_ENABLE
return true; return true;
#endif // MQTT_ENABLE #endif // MQTT_ENABLE
@ -2991,12 +3032,14 @@ void updateClimate(stdAc::state_t *state, const String str,
} else if (str.equals(prefix + F(KEY_POWER))) { } else if (str.equals(prefix + F(KEY_POWER))) {
state->power = IRac::strToBool(payload.c_str()); state->power = IRac::strToBool(payload.c_str());
#if MQTT_CLIMATE_HA_MODE #if MQTT_CLIMATE_HA_MODE
// When in Home Assistant mode, Power Off, means turn the Mode to Off too.
if (!state->power) state->mode = stdAc::opmode_t::kOff; if (!state->power) state->mode = stdAc::opmode_t::kOff;
#endif // MQTT_CLIMATE_HA_MODE #endif // MQTT_CLIMATE_HA_MODE
} else if (str.equals(prefix + F(KEY_MODE))) { } else if (str.equals(prefix + F(KEY_MODE))) {
state->mode = IRac::strToOpmode(payload.c_str()); state->mode = IRac::strToOpmode(payload.c_str());
#if MQTT_CLIMATE_HA_MODE #if MQTT_CLIMATE_HA_MODE
state->power = (state->mode != stdAc::opmode_t::kOff); // When in Home Assistant mode, a Mode of Off, means turn the Power off too.
if (state->mode == stdAc::opmode_t::kOff) state->power = false;
#endif // MQTT_CLIMATE_HA_MODE #endif // MQTT_CLIMATE_HA_MODE
} else if (str.equals(prefix + F(KEY_TEMP))) { } else if (str.equals(prefix + F(KEY_TEMP))) {
state->degrees = payload.toFloat(); state->degrees = payload.toFloat();
@ -3055,7 +3098,7 @@ bool sendClimate(const String topic_prefix, const bool retain,
// Home Assistant want's these two bound together. // Home Assistant want's these two bound together.
if (prev.power != next.power || prev.mode != next.mode || forceMQTT) { if (prev.power != next.power || prev.mode != next.mode || forceMQTT) {
success &= sendBool(topic_prefix + KEY_POWER, next.power, retain); success &= sendBool(topic_prefix + KEY_POWER, next.power, retain);
if (!next.power) mode_str = F("off"); if (!next.power) mode_str = kOffStr;
#else // MQTT_CLIMATE_HA_MODE #else // MQTT_CLIMATE_HA_MODE
// In non-Home Assistant mode, power and mode are not bound together. // In non-Home Assistant mode, power and mode are not bound together.
if (prev.power != next.power || forceMQTT) { if (prev.power != next.power || forceMQTT) {

View File

@ -24,7 +24,12 @@
// An IR detector/demodulator is connected to GPIO pin 14(D5 on a NodeMCU // An IR detector/demodulator is connected to GPIO pin 14(D5 on a NodeMCU
// board). // board).
// Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts.
// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot.
#ifdef ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop.
#else // ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 14; const uint16_t kRecvPin = 14;
#endif // ARDUINO_ESP32C3_DEV
IRrecv irrecv(kRecvPin); IRrecv irrecv(kRecvPin);

View File

@ -38,7 +38,12 @@
// An IR detector/demodulator is connected to GPIO pin 14 // An IR detector/demodulator is connected to GPIO pin 14
// e.g. D5 on a NodeMCU board. // e.g. D5 on a NodeMCU board.
// Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts.
// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot.
#ifdef ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop.
#else // ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 14; const uint16_t kRecvPin = 14;
#endif // ARDUINO_ESP32C3_DEV
// The Serial connection baud rate. // The Serial connection baud rate.
// i.e. Status message will be sent to the PC at this baud rate. // i.e. Status message will be sent to the PC at this baud rate.

View File

@ -45,7 +45,12 @@
// An IR detector/demodulator is connected to GPIO pin 14 // An IR detector/demodulator is connected to GPIO pin 14
// e.g. D5 on a NodeMCU board. // e.g. D5 on a NodeMCU board.
// Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts.
// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot.
#ifdef ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop.
#else // ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 14; const uint16_t kRecvPin = 14;
#endif // ARDUINO_ESP32C3_DEV
// The Serial connection baud rate. // The Serial connection baud rate.
// i.e. Status message will be sent to the PC at this baud rate. // i.e. Status message will be sent to the PC at this baud rate.

View File

@ -60,7 +60,12 @@
// The GPIO an IR detector/demodulator is connected to. Recommended: 14 (D5) // The GPIO an IR detector/demodulator is connected to. Recommended: 14 (D5)
// Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts.
// Note: GPIO 14 won't work on the ESP32-C3 as it causes the board to reboot.
#ifdef ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 10; // 14 on a ESP32-C3 causes a boot loop.
#else // ARDUINO_ESP32C3_DEV
const uint16_t kRecvPin = 14; const uint16_t kRecvPin = 14;
#endif // ARDUINO_ESP32C3_DEV
// GPIO to use to control the IR LED circuit. Recommended: 4 (D2). // GPIO to use to control the IR LED circuit. Recommended: 4 (D2).
const uint16_t kIrLedPin = 4; const uint16_t kIrLedPin = 4;

View File

@ -57,7 +57,7 @@ void setup() {
ac.setFan(1); ac.setFan(1);
ac.setMode(kKelvinatorCool); ac.setMode(kKelvinatorCool);
ac.setTemp(26); ac.setTemp(26);
ac.setSwingVertical(false); ac.setSwingVertical(false, kKelvinatorSwingVOff);
ac.setSwingHorizontal(true); ac.setSwingHorizontal(true);
ac.setXFan(true); ac.setXFan(true);
ac.setIonFilter(false); ac.setIonFilter(false);

View File

@ -47,8 +47,10 @@ IRHaierAC176 KEYWORD1
IRHaierACYRW02 KEYWORD1 IRHaierACYRW02 KEYWORD1
IRHitachiAc KEYWORD1 IRHitachiAc KEYWORD1
IRHitachiAc1 KEYWORD1 IRHitachiAc1 KEYWORD1
IRHitachiAc264 KEYWORD1
IRHitachiAc296 KEYWORD1
IRHitachiAc3 KEYWORD1 IRHitachiAc3 KEYWORD1
IRHitachiAc344: KEYWORD1 IRHitachiAc344 KEYWORD1
IRHitachiAc424 KEYWORD1 IRHitachiAc424 KEYWORD1
IRKelonAc KEYWORD1 IRKelonAc KEYWORD1
IRKelvinatorAC KEYWORD1 IRKelvinatorAC KEYWORD1
@ -120,6 +122,7 @@ _getTime KEYWORD2
_getTimer KEYWORD2 _getTimer KEYWORD2
_isAKB73757604 KEYWORD2 _isAKB73757604 KEYWORD2
_isAKB74955603 KEYWORD2 _isAKB74955603 KEYWORD2
_isLG6711A20083V KEYWORD2
_isNormal KEYWORD2 _isNormal KEYWORD2
_matchGeneric KEYWORD2 _matchGeneric KEYWORD2
_restoreState KEYWORD2 _restoreState KEYWORD2
@ -242,11 +245,13 @@ decodeHaierAC176 KEYWORD2
decodeHaierACYRW02 KEYWORD2 decodeHaierACYRW02 KEYWORD2
decodeHash KEYWORD2 decodeHash KEYWORD2
decodeHitachiAC KEYWORD2 decodeHitachiAC KEYWORD2
decodeHitachiAc296 KEYWORD2
decodeHitachiAc3 KEYWORD2 decodeHitachiAc3 KEYWORD2
decodeHitachiAc424 KEYWORD2 decodeHitachiAc424 KEYWORD2
decodeInax KEYWORD2 decodeInax KEYWORD2
decodeJVC KEYWORD2 decodeJVC KEYWORD2
decodeKelon KEYWORD2 decodeKelon KEYWORD2
decodeKelon168 KEYWORD2
decodeKelvinator KEYWORD2 decodeKelvinator KEYWORD2
decodeLG KEYWORD2 decodeLG KEYWORD2
decodeLasertag KEYWORD2 decodeLasertag KEYWORD2
@ -344,6 +349,7 @@ fujitsu KEYWORD2
get10CHeat KEYWORD2 get10CHeat KEYWORD2
get3D KEYWORD2 get3D KEYWORD2
get8CHeat KEYWORD2 get8CHeat KEYWORD2
get8CHeatToggle KEYWORD2
getAbsenseDetect KEYWORD2 getAbsenseDetect KEYWORD2
getBeep KEYWORD2 getBeep KEYWORD2
getBit KEYWORD2 getBit KEYWORD2
@ -493,12 +499,16 @@ hasInvertedStates KEYWORD2
hasStateChanged KEYWORD2 hasStateChanged KEYWORD2
hitachi KEYWORD2 hitachi KEYWORD2
hitachi1 KEYWORD2 hitachi1 KEYWORD2
hitachi264 KEYWORD2
hitachi296 KEYWORD2
hitachi344 KEYWORD2 hitachi344 KEYWORD2
hitachi424 KEYWORD2 hitachi424 KEYWORD2
htmlEscape KEYWORD2 htmlEscape KEYWORD2
initState KEYWORD2 initState KEYWORD2
int64ToString KEYWORD2 int64ToString KEYWORD2
invertBits KEYWORD2 invertBits KEYWORD2
is8CHeatToggle KEYWORD2
isCleanToggle KEYWORD2
isEconoToggle KEYWORD2 isEconoToggle KEYWORD2
isLightToggle KEYWORD2 isLightToggle KEYWORD2
isOffCommand KEYWORD2 isOffCommand KEYWORD2
@ -508,6 +518,7 @@ isOnTimerActive KEYWORD2
isOnTimerEnabled KEYWORD2 isOnTimerEnabled KEYWORD2
isPowerSpecial KEYWORD2 isPowerSpecial KEYWORD2
isProtocolSupported KEYWORD2 isProtocolSupported KEYWORD2
isQuiet KEYWORD2
isRepeat KEYWORD2 isRepeat KEYWORD2
isSpecialState KEYWORD2 isSpecialState KEYWORD2
isSwing KEYWORD2 isSwing KEYWORD2
@ -617,12 +628,15 @@ sendHaierACYRW02 KEYWORD2
sendHitachiAC KEYWORD2 sendHitachiAC KEYWORD2
sendHitachiAC1 KEYWORD2 sendHitachiAC1 KEYWORD2
sendHitachiAC2 KEYWORD2 sendHitachiAC2 KEYWORD2
sendHitachiAc264 KEYWORD2
sendHitachiAc296 KEYWORD2
sendHitachiAc3 KEYWORD2 sendHitachiAc3 KEYWORD2
sendHitachiAc344 KEYWORD2 sendHitachiAc344 KEYWORD2
sendHitachiAc424 KEYWORD2 sendHitachiAc424 KEYWORD2
sendInax KEYWORD2 sendInax KEYWORD2
sendJVC KEYWORD2 sendJVC KEYWORD2
sendKelon KEYWORD2 sendKelon KEYWORD2
sendKelon168 KEYWORD2
sendKelvinator KEYWORD2 sendKelvinator KEYWORD2
sendLG KEYWORD2 sendLG KEYWORD2
sendLG2 KEYWORD2 sendLG2 KEYWORD2
@ -694,6 +708,7 @@ serialPrintUint64 KEYWORD2
set10CHeat KEYWORD2 set10CHeat KEYWORD2
set3D KEYWORD2 set3D KEYWORD2
set8CHeat KEYWORD2 set8CHeat KEYWORD2
set8CHeatToggle KEYWORD2
setAbsenseDetect KEYWORD2 setAbsenseDetect KEYWORD2
setAuto KEYWORD2 setAuto KEYWORD2
setBeep KEYWORD2 setBeep KEYWORD2
@ -983,12 +998,15 @@ DECODE_HASH LITERAL1
DECODE_HITACHI_AC LITERAL1 DECODE_HITACHI_AC LITERAL1
DECODE_HITACHI_AC1 LITERAL1 DECODE_HITACHI_AC1 LITERAL1
DECODE_HITACHI_AC2 LITERAL1 DECODE_HITACHI_AC2 LITERAL1
DECODE_HITACHI_AC264 LITERAL1
DECODE_HITACHI_AC296 LITERAL1
DECODE_HITACHI_AC3 LITERAL1 DECODE_HITACHI_AC3 LITERAL1
DECODE_HITACHI_AC344 LITERAL1 DECODE_HITACHI_AC344 LITERAL1
DECODE_HITACHI_AC424 LITERAL1 DECODE_HITACHI_AC424 LITERAL1
DECODE_INAX LITERAL1 DECODE_INAX LITERAL1
DECODE_JVC LITERAL1 DECODE_JVC LITERAL1
DECODE_KELON LITERAL1 DECODE_KELON LITERAL1
DECODE_KELON168 LITERAL1
DECODE_KELVINATOR LITERAL1 DECODE_KELVINATOR LITERAL1
DECODE_LASERTAG LITERAL1 DECODE_LASERTAG LITERAL1
DECODE_LEGOPF LITERAL1 DECODE_LEGOPF LITERAL1
@ -1177,6 +1195,10 @@ HITACHI_AC1 LITERAL1
HITACHI_AC1_BITS LITERAL1 HITACHI_AC1_BITS LITERAL1
HITACHI_AC1_STATE_LENGTH LITERAL1 HITACHI_AC1_STATE_LENGTH LITERAL1
HITACHI_AC2 LITERAL1 HITACHI_AC2 LITERAL1
HITACHI_AC264 LITERAL1
HITACHI_AC296 LITERAL1
HITACHI_AC296_BITS LITERAL1
HITACHI_AC296_STATE_LENGTH LITERAL1
HITACHI_AC2_BITS LITERAL1 HITACHI_AC2_BITS LITERAL1
HITACHI_AC2_STATE_LENGTH LITERAL1 HITACHI_AC2_STATE_LENGTH LITERAL1
HITACHI_AC3 LITERAL1 HITACHI_AC3 LITERAL1
@ -1189,6 +1211,7 @@ INAX LITERAL1
JVC LITERAL1 JVC LITERAL1
JVC_BITS LITERAL1 JVC_BITS LITERAL1
KELON LITERAL1 KELON LITERAL1
KELON168 LITERAL1
KELVINATOR LITERAL1 KELVINATOR LITERAL1
KELVINATOR_AUTO LITERAL1 KELVINATOR_AUTO LITERAL1
KELVINATOR_AUTO_TEMP LITERAL1 KELVINATOR_AUTO_TEMP LITERAL1
@ -1210,6 +1233,7 @@ LEGOPF LITERAL1
LG LITERAL1 LG LITERAL1
LG2 LITERAL1 LG2 LITERAL1
LG32_BITS LITERAL1 LG32_BITS LITERAL1
LG6711A20083V LITERAL1
LG_BITS LITERAL1 LG_BITS LITERAL1
LOW LITERAL1 LOW LITERAL1
LUTRON LITERAL1 LUTRON LITERAL1
@ -1337,12 +1361,15 @@ SEND_HAIER_AC_YRW02 LITERAL1
SEND_HITACHI_AC LITERAL1 SEND_HITACHI_AC LITERAL1
SEND_HITACHI_AC1 LITERAL1 SEND_HITACHI_AC1 LITERAL1
SEND_HITACHI_AC2 LITERAL1 SEND_HITACHI_AC2 LITERAL1
SEND_HITACHI_AC264 LITERAL1
SEND_HITACHI_AC296 LITERAL1
SEND_HITACHI_AC3 LITERAL1 SEND_HITACHI_AC3 LITERAL1
SEND_HITACHI_AC344 LITERAL1 SEND_HITACHI_AC344 LITERAL1
SEND_HITACHI_AC424 LITERAL1 SEND_HITACHI_AC424 LITERAL1
SEND_INAX LITERAL1 SEND_INAX LITERAL1
SEND_JVC LITERAL1 SEND_JVC LITERAL1
SEND_KELON LITERAL1 SEND_KELON LITERAL1
SEND_KELON168 LITERAL1
SEND_KELVINATOR LITERAL1 SEND_KELVINATOR LITERAL1
SEND_LASERTAG LITERAL1 SEND_LASERTAG LITERAL1
SEND_LEGOPF LITERAL1 SEND_LEGOPF LITERAL1
@ -1685,7 +1712,6 @@ kCool LITERAL1
kCoolStr LITERAL1 kCoolStr LITERAL1
kCoolingStr LITERAL1 kCoolingStr LITERAL1
kCoolix48Bits LITERAL1 kCoolix48Bits LITERAL1
kCoolix48ExtraTolerance LITERAL1
kCoolixAuto LITERAL1 kCoolixAuto LITERAL1
kCoolixBitMark LITERAL1 kCoolixBitMark LITERAL1
kCoolixBitMarkTicks LITERAL1 kCoolixBitMarkTicks LITERAL1
@ -1696,6 +1722,7 @@ kCoolixCool LITERAL1
kCoolixDefaultRepeat LITERAL1 kCoolixDefaultRepeat LITERAL1
kCoolixDefaultState LITERAL1 kCoolixDefaultState LITERAL1
kCoolixDry LITERAL1 kCoolixDry LITERAL1
kCoolixExtraTolerance LITERAL1
kCoolixFan LITERAL1 kCoolixFan LITERAL1
kCoolixFanAuto LITERAL1 kCoolixFanAuto LITERAL1
kCoolixFanAuto0 LITERAL1 kCoolixFanAuto0 LITERAL1
@ -2426,6 +2453,44 @@ kHitachiAc1TempAuto LITERAL1
kHitachiAc1TempDelta LITERAL1 kHitachiAc1TempDelta LITERAL1
kHitachiAc1TempSize LITERAL1 kHitachiAc1TempSize LITERAL1
kHitachiAc1TimerSize LITERAL1 kHitachiAc1TimerSize LITERAL1
kHitachiAc264Bits LITERAL1
kHitachiAc264ButtonFan LITERAL1
kHitachiAc264ButtonPowerMode LITERAL1
kHitachiAc264ButtonSwingV LITERAL1
kHitachiAc264ButtonTempDown LITERAL1
kHitachiAc264ButtonTempUp LITERAL1
kHitachiAc264Cool LITERAL1
kHitachiAc264Dry LITERAL1
kHitachiAc264Fan LITERAL1
kHitachiAc264FanAuto LITERAL1
kHitachiAc264FanHigh LITERAL1
kHitachiAc264FanLow LITERAL1
kHitachiAc264FanMedium LITERAL1
kHitachiAc264FanMin LITERAL1
kHitachiAc264Heat LITERAL1
kHitachiAc264MaxTemp LITERAL1
kHitachiAc264MinTemp LITERAL1
kHitachiAc264StateLength LITERAL1
kHitachiAc296Auto LITERAL1
kHitachiAc296AutoDehumidifying LITERAL1
kHitachiAc296Bits LITERAL1
kHitachiAc296CondensationControl LITERAL1
kHitachiAc296Cool LITERAL1
kHitachiAc296Dehumidify LITERAL1
kHitachiAc296DryCool LITERAL1
kHitachiAc296FanAuto LITERAL1
kHitachiAc296FanHigh LITERAL1
kHitachiAc296FanLow LITERAL1
kHitachiAc296FanMedium LITERAL1
kHitachiAc296FanSilent LITERAL1
kHitachiAc296Heat LITERAL1
kHitachiAc296MaxTemp LITERAL1
kHitachiAc296MinTemp LITERAL1
kHitachiAc296PowerOff LITERAL1
kHitachiAc296PowerOn LITERAL1
kHitachiAc296QuickLaundry LITERAL1
kHitachiAc296StateLength LITERAL1
kHitachiAc296TempAuto LITERAL1
kHitachiAc2Bits LITERAL1 kHitachiAc2Bits LITERAL1
kHitachiAc2StateLength LITERAL1 kHitachiAc2StateLength LITERAL1
kHitachiAc344Bits LITERAL1 kHitachiAc344Bits LITERAL1
@ -2490,8 +2555,6 @@ kHitachiAc424LdrSpace LITERAL1
kHitachiAc424MaxTemp LITERAL1 kHitachiAc424MaxTemp LITERAL1
kHitachiAc424MinTemp LITERAL1 kHitachiAc424MinTemp LITERAL1
kHitachiAc424OneSpace LITERAL1 kHitachiAc424OneSpace LITERAL1
kHitachiAc424PowerOff LITERAL1
kHitachiAc424PowerOn LITERAL1
kHitachiAc424StateLength LITERAL1 kHitachiAc424StateLength LITERAL1
kHitachiAc424ZeroSpace LITERAL1 kHitachiAc424ZeroSpace LITERAL1
kHitachiAcAuto LITERAL1 kHitachiAcAuto LITERAL1
@ -2553,6 +2616,12 @@ kJvcRptLengthTicks LITERAL1
kJvcTick LITERAL1 kJvcTick LITERAL1
kJvcZeroSpace LITERAL1 kJvcZeroSpace LITERAL1
kJvcZeroSpaceTicks LITERAL1 kJvcZeroSpaceTicks LITERAL1
kKelon168Bits LITERAL1
kKelon168FooterSpace LITERAL1
kKelon168Section1Size LITERAL1
kKelon168Section2Size LITERAL1
kKelon168Section3Size LITERAL1
kKelon168StateLength LITERAL1
kKelonBitMark LITERAL1 kKelonBitMark LITERAL1
kKelonBits LITERAL1 kKelonBits LITERAL1
kKelonDryGradeMax LITERAL1 kKelonDryGradeMax LITERAL1
@ -2602,6 +2671,16 @@ kKelvinatorMinTemp LITERAL1
kKelvinatorOneSpace LITERAL1 kKelvinatorOneSpace LITERAL1
kKelvinatorOneSpaceTicks LITERAL1 kKelvinatorOneSpaceTicks LITERAL1
kKelvinatorStateLength LITERAL1 kKelvinatorStateLength LITERAL1
kKelvinatorSwingVAuto LITERAL1
kKelvinatorSwingVHighAuto LITERAL1
kKelvinatorSwingVHighest LITERAL1
kKelvinatorSwingVLowAuto LITERAL1
kKelvinatorSwingVLowerMiddle LITERAL1
kKelvinatorSwingVLowest LITERAL1
kKelvinatorSwingVMiddle LITERAL1
kKelvinatorSwingVMiddleAuto LITERAL1
kKelvinatorSwingVOff LITERAL1
kKelvinatorSwingVUpperMiddle LITERAL1
kKelvinatorTick LITERAL1 kKelvinatorTick LITERAL1
kKelvinatorZeroSpace LITERAL1 kKelvinatorZeroSpace LITERAL1
kKelvinatorZeroSpaceTicks LITERAL1 kKelvinatorZeroSpaceTicks LITERAL1
@ -2640,6 +2719,7 @@ kLg32Bits LITERAL1
kLg32HdrMark LITERAL1 kLg32HdrMark LITERAL1
kLg32HdrSpace LITERAL1 kLg32HdrSpace LITERAL1
kLg32RptHdrMark LITERAL1 kLg32RptHdrMark LITERAL1
kLg6711a20083vStr LITERAL1
kLgAcAKB74955603DetectionMask LITERAL1 kLgAcAKB74955603DetectionMask LITERAL1
kLgAcAuto LITERAL1 kLgAcAuto LITERAL1
kLgAcChecksumSize LITERAL1 kLgAcChecksumSize LITERAL1
@ -2684,6 +2764,7 @@ kLgAcSwingVOff LITERAL1
kLgAcSwingVOff_Short LITERAL1 kLgAcSwingVOff_Short LITERAL1
kLgAcSwingVSwing LITERAL1 kLgAcSwingVSwing LITERAL1
kLgAcSwingVSwing_Short LITERAL1 kLgAcSwingVSwing_Short LITERAL1
kLgAcSwingVToggle LITERAL1
kLgAcSwingVUpperMiddle LITERAL1 kLgAcSwingVUpperMiddle LITERAL1
kLgAcSwingVUpperMiddle_Short LITERAL1 kLgAcSwingVUpperMiddle_Short LITERAL1
kLgAcTempAdjust LITERAL1 kLgAcTempAdjust LITERAL1
@ -2786,10 +2867,14 @@ kMideaACMinSensorTempC LITERAL1
kMideaACMinSensorTempF LITERAL1 kMideaACMinSensorTempF LITERAL1
kMideaACMinTempC LITERAL1 kMideaACMinTempC LITERAL1
kMideaACMinTempF LITERAL1 kMideaACMinTempF LITERAL1
kMideaACQuietOff LITERAL1
kMideaACQuietOn LITERAL1
kMideaACSensorTempOnTimerOff LITERAL1 kMideaACSensorTempOnTimerOff LITERAL1
kMideaACTimerOff LITERAL1 kMideaACTimerOff LITERAL1
kMideaACToggle8CHeat LITERAL1
kMideaACToggleEcono LITERAL1 kMideaACToggleEcono LITERAL1
kMideaACToggleLight LITERAL1 kMideaACToggleLight LITERAL1
kMideaACToggleSelfClean LITERAL1
kMideaACToggleTurbo LITERAL1 kMideaACToggleTurbo LITERAL1
kMideaACTypeCommand LITERAL1 kMideaACTypeCommand LITERAL1
kMideaACTypeFollow LITERAL1 kMideaACTypeFollow LITERAL1

View File

@ -1,6 +1,6 @@
{ {
"name": "IRremoteESP8266", "name": "IRremoteESP8266",
"version": "2.8.1", "version": "2.8.2",
"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.8.1 version=2.8.2
author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff
maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto, Christian Nilsson maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto, Christian Nilsson
sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32) sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32)

View File

@ -71,7 +71,6 @@ IRac::IRac(const uint16_t pin, const bool inverted, const bool use_modulation) {
_pin = pin; _pin = pin;
_inverted = inverted; _inverted = inverted;
_modulation = use_modulation; _modulation = use_modulation;
initState(&next);
this->markAsSent(); this->markAsSent();
} }
@ -132,11 +131,8 @@ void IRac::initState(stdAc::state_t *state,
/// @param[out] state A Ptr to where the settings will be stored. /// @param[out] state A Ptr to where the settings will be stored.
/// @note Sets all the parameters to reasonable base/automatic defaults. /// @note Sets all the parameters to reasonable base/automatic defaults.
void IRac::initState(stdAc::state_t *state) { void IRac::initState(stdAc::state_t *state) {
initState(state, decode_type_t::UNKNOWN, -1, false, stdAc::opmode_t::kOff, stdAc::state_t def;
25, true, // 25 degrees Celsius *state = def;
stdAc::fanspeed_t::kAuto, stdAc::swingv_t::kOff,
stdAc::swingh_t::kOff, false, false, false, false, false, false,
false, -1, -1);
} }
/// Get the current internal A/C climate state. /// Get the current internal A/C climate state.
@ -231,6 +227,12 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#if SEND_HITACHI_AC1 #if SEND_HITACHI_AC1
case decode_type_t::HITACHI_AC1: case decode_type_t::HITACHI_AC1:
#endif #endif
#if SEND_HITACHI_AC264
case decode_type_t::HITACHI_AC264:
#endif
#if SEND_HITACHI_AC296
case decode_type_t::HITACHI_AC296:
#endif
#if SEND_HITACHI_AC344 #if SEND_HITACHI_AC344
case decode_type_t::HITACHI_AC344: case decode_type_t::HITACHI_AC344:
#endif #endif
@ -1313,6 +1315,64 @@ void IRac::hitachi1(IRHitachiAc1 *ac, const hitachi_ac1_remote_model_t model,
} }
#endif // SEND_HITACHI_AC1 #endif // SEND_HITACHI_AC1
#if SEND_HITACHI_AC264
/// Send a Hitachi 264-bit A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRHitachiAc264 object to use.
/// @param[in] on The power setting.
/// @param[in] mode The operation mode setting.
/// @param[in] degrees The temperature setting in degrees.
/// @param[in] fan The speed setting for the fan.
void IRac::hitachi264(IRHitachiAc264 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan) {
ac->begin();
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setPower(on);
// No Swing(V) setting available.
// No Swing(H) setting available.
// No Quiet setting available.
// No Turbo setting available.
// No Light setting available.
// No Filter setting available.
// No Clean setting available.
// No Beep setting available.
// No Sleep setting available.
// No Clock setting available.
ac->send();
}
#endif // SEND_HITACHI_AC264
#if SEND_HITACHI_AC296
/// Send a Hitachi 296-bit A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRHitachiAc296 object to use.
/// @param[in] on The power setting.
/// @param[in] mode The operation mode setting.
/// @param[in] degrees The temperature setting in degrees.
/// @param[in] fan The speed setting for the fan.
void IRac::hitachi296(IRHitachiAc296 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan) {
ac->begin();
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setPower(on);
// No Swing(V) setting available.
// No Swing(H) setting available.
// No Quiet setting available.
// No Turbo setting available.
// No Light setting available.
// No Filter setting available.
// No Clean setting available.
// No Beep setting available.
// No Sleep setting available.
// No Clock setting available.
ac->send();
}
#endif // SEND_HITACHI_AC296
#if SEND_HITACHI_AC344 #if SEND_HITACHI_AC344
/// Send a Hitachi 344-bit A/C message with the supplied settings. /// Send a Hitachi 344-bit A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRHitachiAc344 object to use. /// @param[in, out] ac A Ptr to an IRHitachiAc344 object to use.
@ -1437,7 +1497,8 @@ void IRac::kelvinator(IRKelvinatorAC *ac,
ac->setMode(ac->convertMode(mode)); ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees); ac->setTemp(degrees);
ac->setFan((uint8_t)fan); // No conversion needed. ac->setFan((uint8_t)fan); // No conversion needed.
ac->setSwingVertical((int8_t)swingv >= 0); ac->setSwingVertical(swingv == stdAc::swingv_t::kAuto, // Set auto flag.
ac->convertSwingV(swingv));
ac->setSwingHorizontal((int8_t)swingh >= 0); ac->setSwingHorizontal((int8_t)swingh >= 0);
ac->setQuiet(quiet); ac->setQuiet(quiet);
ac->setTurbo(turbo); ac->setTurbo(turbo);
@ -1480,6 +1541,12 @@ void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model,
const uint8_t pos = ac->convertVaneSwingV(swingv); const uint8_t pos = ac->convertVaneSwingV(swingv);
for (uint8_t vane = 0; vane < kLgAcSwingVMaxVanes; vane++) for (uint8_t vane = 0; vane < kLgAcSwingVMaxVanes; vane++)
ac->setVaneSwingV(vane, pos); ac->setVaneSwingV(vane, pos);
// Toggle the swingv for LG6711A20083V models if we need to.
// i.e. Off to Not-Off, send a toggle. Not-Off to Off, send a toggle.
if ((model == lg_ac_remote_model_t::LG6711A20083V) &&
((swingv == stdAc::swingv_t::kOff) !=
(swingv_prev == stdAc::swingv_t::kOff)))
ac->setSwingV(kLgAcSwingVToggle);
ac->setSwingH(swingh != stdAc::swingh_t::kOff); ac->setSwingH(swingh != stdAc::swingh_t::kOff);
// No Quiet setting available. // No Quiet setting available.
// No Turbo setting available. // No Turbo setting available.
@ -1502,16 +1569,21 @@ void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model,
/// @param[in] degrees The temperature setting in degrees. /// @param[in] degrees The temperature setting in degrees.
/// @param[in] fan The speed setting for the fan. /// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting. /// @param[in] swingv The vertical swing setting.
/// @param[in] quiet Run the device in quiet/silent mode.
/// @param[in] quiet_prev The device's previous quiet/silent mode.
/// @param[in] turbo Toggle the device's turbo/powerful mode. /// @param[in] turbo Toggle the device's turbo/powerful mode.
/// @param[in] econo Toggle the device's economical mode. /// @param[in] econo Toggle the device's economical mode.
/// @param[in] light Toggle the LED/Display mode. /// @param[in] light Toggle the LED/Display mode.
/// @param[in] clean Turn on the self-cleaning mode. e.g. XFan, dry filters etc
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on. /// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
/// @note On Danby A/C units, swingv controls the Ion Filter instead. /// @note On Danby A/C units, swingv controls the Ion Filter instead.
void IRac::midea(IRMideaAC *ac, void IRac::midea(IRMideaAC *ac,
const bool on, const stdAc::opmode_t mode, const bool celsius, const bool on, const stdAc::opmode_t mode, const bool celsius,
const float degrees, const stdAc::fanspeed_t fan, const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const bool turbo, const stdAc::swingv_t swingv,
const bool econo, const bool light, const int16_t sleep) { const bool quiet, const bool quiet_prev,
const bool turbo, const bool econo, const bool light,
const bool clean, const int16_t sleep) {
ac->begin(); ac->begin();
ac->setPower(on); ac->setPower(on);
ac->setMode(ac->convertMode(mode)); ac->setMode(ac->convertMode(mode));
@ -1520,12 +1592,12 @@ void IRac::midea(IRMideaAC *ac,
ac->setFan(ac->convertFan(fan)); ac->setFan(ac->convertFan(fan));
ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff); ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff);
// No Horizontal swing setting available. // No Horizontal swing setting available.
// No Quiet setting available. ac->setQuiet(quiet, quiet_prev);
ac->setTurboToggle(turbo); ac->setTurboToggle(turbo);
ac->setEconoToggle(econo); ac->setEconoToggle(econo);
ac->setLightToggle(light); ac->setLightToggle(light);
// No Filter setting available. // No Filter setting available.
// No Clean setting available. ac->setCleanToggle(clean);
// No Beep setting available. // No Beep setting available.
ac->setSleep(sleep >= 0); // Sleep on this A/C is either on or off. ac->setSleep(sleep >= 0); // Sleep on this A/C is either on or off.
// No Clock setting available. // No Clock setting available.
@ -2530,6 +2602,7 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired,
result.turbo = desired.turbo ^ prev->turbo; result.turbo = desired.turbo ^ prev->turbo;
result.econo = desired.econo ^ prev->econo; result.econo = desired.econo ^ prev->econo;
result.light = desired.light ^ prev->light; result.light = desired.light ^ prev->light;
result.clean = desired.clean ^ prev->clean;
// FALL THRU // FALL THRU
case decode_type_t::CORONA_AC: case decode_type_t::CORONA_AC:
case decode_type_t::HITACHI_AC344: case decode_type_t::HITACHI_AC344:
@ -2645,6 +2718,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
const stdAc::swingv_t prev_swingv = (prev != NULL) ? prev->swingv const stdAc::swingv_t prev_swingv = (prev != NULL) ? prev->swingv
: stdAc::swingv_t::kOff; : stdAc::swingv_t::kOff;
#endif // (SEND_LG || SEND_SHARP_AC) #endif // (SEND_LG || SEND_SHARP_AC)
#if SEND_MIDEA
const bool prev_quiet = (prev != NULL) ? prev->quiet : !send.quiet;
#endif // SEND_MIDEA
// Per vendor settings & setup. // Per vendor settings & setup.
switch (send.protocol) { switch (send.protocol) {
#if SEND_AIRTON #if SEND_AIRTON
@ -2894,6 +2970,22 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
break; break;
} }
#endif // SEND_HITACHI_AC1 #endif // SEND_HITACHI_AC1
#if SEND_HITACHI_AC264
case HITACHI_AC264:
{
IRHitachiAc264 ac(_pin, _inverted, _modulation);
hitachi264(&ac, send.power, send.mode, degC, send.fanspeed);
break;
}
#endif // SEND_HITACHI_AC264
#if SEND_HITACHI_AC296
case HITACHI_AC296:
{
IRHitachiAc296 ac(_pin, _inverted, _modulation);
hitachi296(&ac, send.power, send.mode, degC, send.fanspeed);
break;
}
#endif // SEND_HITACHI_AC296
#if SEND_HITACHI_AC344 #if SEND_HITACHI_AC344
case HITACHI_AC344: case HITACHI_AC344:
{ {
@ -2945,8 +3037,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
{ {
IRMideaAC ac(_pin, _inverted, _modulation); IRMideaAC ac(_pin, _inverted, _modulation);
midea(&ac, send.power, send.mode, send.celsius, send.degrees, midea(&ac, send.power, send.mode, send.celsius, send.degrees,
send.fanspeed, send.swingv, send.turbo, send.econo, send.light, send.fanspeed, send.swingv, send.quiet, prev_quiet, send.turbo,
send.sleep); send.econo, send.light, send.sleep);
break; break;
} }
#endif // SEND_MIDEA #endif // SEND_MIDEA
@ -3412,6 +3504,8 @@ int16_t IRac::strToModel(const char *str, const int16_t def) {
return lg_ac_remote_model_t::AKB74955603; return lg_ac_remote_model_t::AKB74955603;
} else if (!STRCASECMP(str, kAkb73757604Str)) { } else if (!STRCASECMP(str, kAkb73757604Str)) {
return lg_ac_remote_model_t::AKB73757604; return lg_ac_remote_model_t::AKB73757604;
} else if (!STRCASECMP(str, kLg6711a20083vStr)) {
return lg_ac_remote_model_t::LG6711A20083V;
// Panasonic A/C families // Panasonic A/C families
} else if (!STRCASECMP(str, kLkeStr) || } else if (!STRCASECMP(str, kLkeStr) ||
!STRCASECMP(str, kPanasonicLkeStr)) { !STRCASECMP(str, kPanasonicLkeStr)) {
@ -3747,6 +3841,20 @@ namespace IRAcUtils {
return ac.toString(); return ac.toString();
} }
#endif // DECODE_HITACHI_AC1 #endif // DECODE_HITACHI_AC1
#if DECODE_HITACHI_AC264
case decode_type_t::HITACHI_AC264: {
IRHitachiAc264 ac(kGpioUnused);
ac.setRaw(result->state);
return ac.toString();
}
#endif // DECODE_HITACHI_AC264
#if DECODE_HITACHI_AC296
case decode_type_t::HITACHI_AC296: {
IRHitachiAc296 ac(kGpioUnused);
ac.setRaw(result->state);
return ac.toString();
}
#endif // DECODE_HITACHI_AC296
#if DECODE_HITACHI_AC344 #if DECODE_HITACHI_AC344
case decode_type_t::HITACHI_AC344: { case decode_type_t::HITACHI_AC344: {
IRHitachiAc344 ac(kGpioUnused); IRHitachiAc344 ac(kGpioUnused);
@ -4204,6 +4312,22 @@ namespace IRAcUtils {
break; break;
} }
#endif // DECODE_HITACHI_AC1 #endif // DECODE_HITACHI_AC1
#if DECODE_HITACHI_AC264
case decode_type_t::HITACHI_AC264: {
IRHitachiAc264 ac(kGpioUnused);
ac.setRaw(decode->state);
*result = ac.toCommon();
break;
}
#endif // DECODE_HITACHI_AC264
#if DECODE_HITACHI_AC296
case decode_type_t::HITACHI_AC296: {
IRHitachiAc296 ac(kGpioUnused);
ac.setRaw(decode->state);
*result = ac.toCommon();
break;
}
#endif // DECODE_HITACHI_AC296
#if DECODE_HITACHI_AC344 #if DECODE_HITACHI_AC344
case decode_type_t::HITACHI_AC344: { case decode_type_t::HITACHI_AC344: {
IRHitachiAc344 ac(kGpioUnused); IRHitachiAc344 ac(kGpioUnused);

View File

@ -300,6 +300,16 @@ void electra(IRElectraAc *ac,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh, const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
const bool swing_toggle, const int16_t sleep = -1); const bool swing_toggle, const int16_t sleep = -1);
#endif // SEND_HITACHI_AC1 #endif // SEND_HITACHI_AC1
#if SEND_HITACHI_AC264
void hitachi264(IRHitachiAc264 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan);
#endif // SEND_HITACHI_AC264
#if SEND_HITACHI_AC296
void hitachi296(IRHitachiAc296 *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan);
#endif // SEND_HITACHI_AC296
#if SEND_HITACHI_AC344 #if SEND_HITACHI_AC344
void hitachi344(IRHitachiAc344 *ac, void hitachi344(IRHitachiAc344 *ac,
const bool on, const stdAc::opmode_t mode, const bool on, const stdAc::opmode_t mode,
@ -338,8 +348,10 @@ void electra(IRElectraAc *ac,
void midea(IRMideaAC *ac, void midea(IRMideaAC *ac,
const bool on, const stdAc::opmode_t mode, const bool celsius, const bool on, const stdAc::opmode_t mode, const bool celsius,
const float degrees, const stdAc::fanspeed_t fan, const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const bool turbo, const bool econo, const stdAc::swingv_t swingv,
const bool light, const int16_t sleep = -1); const bool quiet, const bool quiet_prev, const bool turbo,
const bool econo, const bool light, const bool clean,
const int16_t sleep = -1);
#endif // SEND_MIDEA #endif // SEND_MIDEA
#if SEND_MIRAGE #if SEND_MIRAGE
void mirage(IRMirageAc *ac, const stdAc::state_t state); void mirage(IRMirageAc *ac, const stdAc::state_t state);

View File

@ -261,13 +261,20 @@ static void USE_IRAM_ATTR gpio_intr() {
/// capturing data. (Default: kTimeoutMs) /// capturing data. (Default: kTimeoutMs)
/// @param[in] save_buffer Use a second (save) buffer to decode from. /// @param[in] save_buffer Use a second (save) buffer to decode from.
/// (Default: false) /// (Default: false)
/// @param[in] timer_num Nr. of the ESP32 timer to use (0 to 3) (ESP32 Only) /// @param[in] timer_num Nr. of the ESP32 timer to use. (0 to 3) (ESP32 Only)
/// or (0 to 1) (ESP32-C3)
#if defined(ESP32) #if defined(ESP32)
IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize, IRrecv::IRrecv(const uint16_t recvpin, const uint16_t bufsize,
const uint8_t timeout, const bool save_buffer, const uint8_t timeout, const bool save_buffer,
const uint8_t timer_num) { const uint8_t timer_num) {
// There are only 4 timers. 0 to 3. // Ensure we use a valid timer number.
_timer_num = std::min(timer_num, (uint8_t)3); _timer_num = std::min(timer_num,
(uint8_t)(
#ifdef SOC_TIMER_GROUP_TOTAL_TIMERS
SOC_TIMER_GROUP_TOTAL_TIMERS - 1));
#else // SOC_TIMER_GROUP_TOTAL_TIMERS
3));
#endif // SOC_TIMER_GROUP_TOTAL_TIMERS
#else // ESP32 #else // ESP32
/// @cond IGNORE /// @cond IGNORE
/// Class constructor /// Class constructor
@ -353,6 +360,13 @@ void IRrecv::enableIRIn(const bool pullup) {
// Initialise the ESP32 timer. // Initialise the ESP32 timer.
// 80MHz / 80 = 1 uSec granularity. // 80MHz / 80 = 1 uSec granularity.
timer = timerBegin(_timer_num, 80, true); timer = timerBegin(_timer_num, 80, true);
#ifdef DEBUG
if (timer == NULL) {
DPRINT("FATAL: Unable enable system timer: ");
DPRINTLN((uint16_t)_timer_num);
}
#endif // DEBUG
assert(timer != NULL); // Check we actually got the timer.
// Set the timer so it only fires once, and set it's trigger in uSeconds. // Set the timer so it only fires once, and set it's trigger in uSeconds.
timerAlarmWrite(timer, MS_TO_USEC(params.timeout), ONCE); timerAlarmWrite(timer, MS_TO_USEC(params.timeout), ONCE);
// Note: Interrupt needs to be attached before it can be enabled or disabled. // Note: Interrupt needs to be attached before it can be enabled or disabled.
@ -830,6 +844,18 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
if (decodeHitachiAC(results, offset, kHitachiAc344Bits, true, false)) if (decodeHitachiAC(results, offset, kHitachiAc344Bits, true, false))
return true; return true;
#endif // DECODE_HITACHI_AC344 #endif // DECODE_HITACHI_AC344
#if DECODE_HITACHI_AC264
// HitachiAC264 should be checked before HitachiAC
DPRINTLN("Attempting Hitachi AC264 decode");
if (decodeHitachiAC(results, offset, kHitachiAc264Bits, true, false))
return true;
#endif // DECODE_HITACHI_AC264
#if DECODE_HITACHI_AC296
// HitachiAC296 should be checked before HitachiAC
DPRINTLN("Attempting Hitachi AC296 decode");
if (decodeHitachiAc296(results, offset, kHitachiAc296Bits, true))
return true;
#endif // DECODE_HITACHI_AC296
#if DECODE_HITACHI_AC2 #if DECODE_HITACHI_AC2
// HitachiAC2 should be checked before HitachiAC // HitachiAC2 should be checked before HitachiAC
DPRINTLN("Attempting Hitachi AC2 decode"); DPRINTLN("Attempting Hitachi AC2 decode");
@ -1044,8 +1070,12 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
DPRINTLN("Attempting Teknopoint decode"); DPRINTLN("Attempting Teknopoint decode");
if (decodeTeknopoint(results, offset)) return true; if (decodeTeknopoint(results, offset)) return true;
#endif // DECODE_TEKNOPOINT #endif // DECODE_TEKNOPOINT
#if DECODE_KELON168
DPRINTLN("Attempting Kelon 168-bit decode");
if (decodeKelon168(results, offset)) return true;
#endif // DECODE_KELON168
#if DECODE_KELON #if DECODE_KELON
DPRINTLN("Attempting Kelon decode"); DPRINTLN("Attempting Kelon 48-bit decode");
if (decodeKelon(results, offset)) return true; if (decodeKelon(results, offset)) return true;
#endif // DECODE_KELON #endif // DECODE_KELON
#if DECODE_SANYO_AC88 #if DECODE_SANYO_AC88
@ -1166,8 +1196,8 @@ bool IRrecv::matchAtLeast(uint32_t measured, uint32_t desired,
DPRINT(". Matching: "); DPRINT(". Matching: ");
DPRINT(measured); DPRINT(measured);
DPRINT(" >= "); DPRINT(" >= ");
DPRINT(ticksLow(std::min(desired, MS_TO_USEC(params.timeout)), tolerance, DPRINT(ticksLow(std::min(desired, (uint32_t)MS_TO_USEC(params.timeout)),
delta)); tolerance, delta));
DPRINT(" [min("); DPRINT(" [min(");
DPRINT(ticksLow(desired, tolerance, delta)); DPRINT(ticksLow(desired, tolerance, delta));
DPRINT(", "); DPRINT(", ");

View File

@ -52,8 +52,15 @@ const uint16_t kMaxTimeoutMs = kRawTick * (UINT16_MAX / MS_TO_USEC(1));
const uint32_t kFnvPrime32 = 16777619UL; const uint32_t kFnvPrime32 = 16777619UL;
const uint32_t kFnvBasis32 = 2166136261UL; const uint32_t kFnvBasis32 = 2166136261UL;
// Which of the ESP32 timers to use by default. (0-3) #ifdef ESP32
// Which of the ESP32 timers to use by default.
// (3 for most ESP32s, 1 for ESP32-C3s)
#ifdef SOC_TIMER_GROUP_TOTAL_TIMERS
const uint8_t kDefaultESP32Timer = SOC_TIMER_GROUP_TOTAL_TIMERS - 1;
#else // SOC_TIMER_GROUP_TOTAL_TIMERS
const uint8_t kDefaultESP32Timer = 3; const uint8_t kDefaultESP32Timer = 3;
#endif // SOC_TIMER_GROUP_TOTAL_TIMERS
#endif // ESP32
#if DECODE_AC #if DECODE_AC
// Hitachi AC is the current largest state size. // Hitachi AC is the current largest state size.
@ -590,11 +597,13 @@ class IRrecv {
const uint16_t nbits = kHaierAC176Bits, const uint16_t nbits = kHaierAC176Bits,
const bool strict = true); const bool strict = true);
#endif // DECODE_HAIER_AC176 #endif // DECODE_HAIER_AC176
#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC344) #if (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC264 || \
DECODE_HITACHI_AC344)
bool decodeHitachiAC(decode_results *results, uint16_t offset = kStartOffset, bool decodeHitachiAC(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAcBits, const uint16_t nbits = kHitachiAcBits,
const bool strict = true, const bool MSBfirst = true); const bool strict = true, const bool MSBfirst = true);
#endif #endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC2 || DECODE_HITACHI_AC264 ||
// DECODE_HITACHI_AC344)
#if DECODE_HITACHI_AC1 #if DECODE_HITACHI_AC1
bool decodeHitachiAC1(decode_results *results, uint16_t offset = kStartOffset, bool decodeHitachiAC1(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc1Bits, const uint16_t nbits = kHitachiAc1Bits,
@ -606,6 +615,12 @@ class IRrecv {
const uint16_t nbits = kHitachiAc3Bits, const uint16_t nbits = kHitachiAc3Bits,
const bool strict = true); const bool strict = true);
#endif // DECODE_HITACHI_AC3 #endif // DECODE_HITACHI_AC3
#if DECODE_HITACHI_AC296
bool decodeHitachiAc296(decode_results *results,
uint16_t offset = kStartOffset,
const uint16_t nbits = kHitachiAc296Bits,
const bool strict = true);
#endif // DECODE_HITACHI_AC296
#if DECODE_HITACHI_AC424 #if DECODE_HITACHI_AC424
bool decodeHitachiAc424(decode_results *results, bool decodeHitachiAc424(decode_results *results,
uint16_t offset = kStartOffset, uint16_t offset = kStartOffset,
@ -771,6 +786,11 @@ class IRrecv {
bool decodeKelon(decode_results *results, uint16_t offset = kStartOffset, bool decodeKelon(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kKelonBits, const bool strict = true); const uint16_t nbits = kKelonBits, const bool strict = true);
#endif // DECODE_KELON #endif // DECODE_KELON
#if DECODE_KELON168
bool decodeKelon168(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kKelon168Bits,
const bool strict = true);
#endif // DECODE_KELON168
#if DECODE_BOSE #if DECODE_BOSE
bool decodeBose(decode_results *results, uint16_t offset = kStartOffset, bool decodeBose(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kBoseBits, const bool strict = true); const uint16_t nbits = kBoseBits, const bool strict = true);

View File

@ -58,12 +58,13 @@
// Minor version number (x.X.x) // Minor version number (x.X.x)
#define _IRREMOTEESP8266_VERSION_MINOR 8 #define _IRREMOTEESP8266_VERSION_MINOR 8
// Patch version number (x.x.X) // Patch version number (x.x.X)
#define _IRREMOTEESP8266_VERSION_PATCH 1 #define _IRREMOTEESP8266_VERSION_PATCH 2
// Macro to convert version info into an integer // Macro to convert version info into an integer
#define _IRREMOTEESP8266_VERSION_VAL(major, minor, patch) \ #define _IRREMOTEESP8266_VERSION_VAL(major, minor, patch) \
((major << 16) | (minor << 8) | (patch)) ((major << 16) | (minor << 8) | (patch))
// Macro to convert literal into a string // Macro to convert literal into a string
#define MKSTR(x) #x #define MKSTR_HELPER(x) #x
#define MKSTR(x) MKSTR_HELPER(x)
// Integer version // Integer version
#define _IRREMOTEESP8266_VERSION _IRREMOTEESP8266_VERSION_VAL(\ #define _IRREMOTEESP8266_VERSION _IRREMOTEESP8266_VERSION_VAL(\
_IRREMOTEESP8266_VERSION_MAJOR, \ _IRREMOTEESP8266_VERSION_MAJOR, \
@ -489,6 +490,20 @@
#define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_ #define SEND_HITACHI_AC3 _IR_ENABLE_DEFAULT_
#endif // SEND_HITACHI_AC3 #endif // SEND_HITACHI_AC3
#ifndef DECODE_HITACHI_AC264
#define DECODE_HITACHI_AC264 _IR_ENABLE_DEFAULT_
#endif // DECODE_HITACHI_AC264
#ifndef SEND_HITACHI_AC264
#define SEND_HITACHI_AC264 _IR_ENABLE_DEFAULT_
#endif // SEND_HITACHI_AC264
#ifndef DECODE_HITACHI_AC296
#define DECODE_HITACHI_AC296 _IR_ENABLE_DEFAULT_
#endif // DECODE_HITACHI_AC296
#ifndef SEND_HITACHI_AC296
#define SEND_HITACHI_AC296 _IR_ENABLE_DEFAULT_
#endif // SEND_HITACHI_AC296
#ifndef DECODE_HITACHI_AC344 #ifndef DECODE_HITACHI_AC344
#define DECODE_HITACHI_AC344 _IR_ENABLE_DEFAULT_ #define DECODE_HITACHI_AC344 _IR_ENABLE_DEFAULT_
#endif // DECODE_HITACHI_AC344 #endif // DECODE_HITACHI_AC344
@ -839,6 +854,13 @@
#define SEND_AIRTON _IR_ENABLE_DEFAULT_ #define SEND_AIRTON _IR_ENABLE_DEFAULT_
#endif // SEND_AIRTON #endif // SEND_AIRTON
#ifndef DECODE_KELON168
#define DECODE_KELON168 _IR_ENABLE_DEFAULT_
#endif // DECODE_KELON168
#ifndef SEND_KELON168
#define SEND_KELON168 _IR_ENABLE_DEFAULT_
#endif // SEND_KELON168
#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 || \
@ -853,7 +875,8 @@
DECODE_HITACHI_AC344 || DECODE_CORONA_AC || DECODE_SANYO_AC || \ DECODE_HITACHI_AC344 || DECODE_CORONA_AC || DECODE_SANYO_AC || \
DECODE_VOLTAS || DECODE_MIRAGE || DECODE_HAIER_AC176 || \ DECODE_VOLTAS || DECODE_MIRAGE || DECODE_HAIER_AC176 || \
DECODE_TEKNOPOINT || DECODE_KELON || DECODE_TROTEC_3550 || \ DECODE_TEKNOPOINT || DECODE_KELON || DECODE_TROTEC_3550 || \
DECODE_SANYO_AC88 || DECODE_RHOSS || \ DECODE_SANYO_AC88 || DECODE_RHOSS || DECODE_HITACHI_AC264 || \
DECODE_KELON168 || DECODE_HITACHI_AC296 || \
false) false)
// Add any DECODE to the above if it uses result->state (see kStateSizeMax) // Add any DECODE to the above if it uses result->state (see kStateSizeMax)
// you might also want to add the protocol to hasACState function // you might also want to add the protocol to hasACState function
@ -1004,8 +1027,11 @@ enum decode_type_t {
RHOSS, RHOSS,
AIRTON, AIRTON,
COOLIX48, // 110 COOLIX48, // 110
HITACHI_AC264,
KELON168,
HITACHI_AC296,
// 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 = COOLIX48, kLastDecodeType = HITACHI_AC296,
}; };
// Message lengths & required repeat values // Message lengths & required repeat values
@ -1115,6 +1141,10 @@ const uint16_t kHitachiAc3StateLength = 27;
const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8; const uint16_t kHitachiAc3Bits = kHitachiAc3StateLength * 8;
const uint16_t kHitachiAc3MinStateLength = 15; const uint16_t kHitachiAc3MinStateLength = 15;
const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8; const uint16_t kHitachiAc3MinBits = kHitachiAc3MinStateLength * 8;
const uint16_t kHitachiAc264StateLength = 33;
const uint16_t kHitachiAc264Bits = kHitachiAc264StateLength * 8;
const uint16_t kHitachiAc296StateLength = 37;
const uint16_t kHitachiAc296Bits = kHitachiAc296StateLength * 8;
const uint16_t kHitachiAc344StateLength = 43; const uint16_t kHitachiAc344StateLength = 43;
const uint16_t kHitachiAc344Bits = kHitachiAc344StateLength * 8; const uint16_t kHitachiAc344Bits = kHitachiAc344StateLength * 8;
const uint16_t kHitachiAc424StateLength = 53; const uint16_t kHitachiAc424StateLength = 53;
@ -1123,6 +1153,8 @@ const uint16_t kInaxBits = 24;
const uint16_t kInaxMinRepeat = kSingleRepeat; const uint16_t kInaxMinRepeat = kSingleRepeat;
const uint16_t kJvcBits = 16; const uint16_t kJvcBits = 16;
const uint16_t kKelonBits = 48; const uint16_t kKelonBits = 48;
const uint16_t kKelon168StateLength = 21;
const uint16_t kKelon168Bits = kKelon168StateLength * 8;
const uint16_t kKelvinatorStateLength = 16; const uint16_t kKelvinatorStateLength = 16;
const uint16_t kKelvinatorBits = kKelvinatorStateLength * 8; const uint16_t kKelvinatorBits = kKelvinatorStateLength * 8;
const uint16_t kKelvinatorDefaultRepeat = kNoRepeat; const uint16_t kKelvinatorDefaultRepeat = kNoRepeat;
@ -1282,6 +1314,8 @@ const uint16_t kRhossDefaultRepeat = 0;
#define HITACHI_AC1_BITS kHitachiAc1Bits #define HITACHI_AC1_BITS kHitachiAc1Bits
#define HITACHI_AC2_STATE_LENGTH kHitachiAc2StateLength #define HITACHI_AC2_STATE_LENGTH kHitachiAc2StateLength
#define HITACHI_AC2_BITS kHitachiAc2Bits #define HITACHI_AC2_BITS kHitachiAc2Bits
#define HITACHI_AC296_STATE_LENGTH kHitachiAc296StateLength
#define HITACHI_AC296_BITS kHitachiAc296Bits
#define JVC_BITS kJvcBits #define JVC_BITS kJvcBits
#define KELVINATOR_STATE_LENGTH kKelvinatorStateLength #define KELVINATOR_STATE_LENGTH kKelvinatorStateLength
#define LASERTAG_BITS kLasertagBits #define LASERTAG_BITS kLasertagBits

View File

@ -718,10 +718,16 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
return kHitachiAc2Bits; return kHitachiAc2Bits;
case HITACHI_AC3: case HITACHI_AC3:
return kHitachiAc3Bits; return kHitachiAc3Bits;
case HITACHI_AC264:
return kHitachiAc264Bits;
case HITACHI_AC296:
return kHitachiAc296Bits;
case HITACHI_AC344: case HITACHI_AC344:
return kHitachiAc344Bits; return kHitachiAc344Bits;
case HITACHI_AC424: case HITACHI_AC424:
return kHitachiAc424Bits; return kHitachiAc424Bits;
case KELON168:
return kKelon168Bits;
case KELVINATOR: case KELVINATOR:
return kKelvinatorBits; return kKelvinatorBits;
case MILESTAG2: case MILESTAG2:
@ -1210,6 +1216,16 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
sendHitachiAc3(state, nbytes); sendHitachiAc3(state, nbytes);
break; break;
#endif // SEND_HITACHI_AC3 #endif // SEND_HITACHI_AC3
#if SEND_HITACHI_AC264
case HITACHI_AC264:
sendHitachiAc264(state, nbytes);
break;
#endif // SEND_HITACHI_AC264
#if SEND_HITACHI_AC296
case HITACHI_AC296:
sendHitachiAc296(state, nbytes);
break;
#endif // SEND_HITACHI_AC296
#if SEND_HITACHI_AC344 #if SEND_HITACHI_AC344
case HITACHI_AC344: case HITACHI_AC344:
sendHitachiAc344(state, nbytes); sendHitachiAc344(state, nbytes);
@ -1220,6 +1236,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
sendHitachiAc424(state, nbytes); sendHitachiAc424(state, nbytes);
break; break;
#endif // SEND_HITACHI_AC424 #endif // SEND_HITACHI_AC424
#if SEND_KELON168
case KELON168:
sendKelon168(state, nbytes);
break;
#endif // SEND_KELON168
#if SEND_KELVINATOR #if SEND_KELVINATOR
case KELVINATOR: case KELVINATOR:
sendKelvinator(state, nbytes); sendKelvinator(state, nbytes);

View File

@ -95,24 +95,24 @@ enum class swingh_t {
/// Structure to hold a common A/C state. /// Structure to hold a common A/C state.
struct state_t { struct state_t {
decode_type_t protocol; decode_type_t protocol = decode_type_t::UNKNOWN;
int16_t model; int16_t model = -1; // `-1` means unused.
bool power; bool power = false;
stdAc::opmode_t mode; stdAc::opmode_t mode = stdAc::opmode_t::kOff;
float degrees; float degrees = 25;
bool celsius; bool celsius = true;
stdAc::fanspeed_t fanspeed; stdAc::fanspeed_t fanspeed = stdAc::fanspeed_t::kAuto;
stdAc::swingv_t swingv; stdAc::swingv_t swingv = stdAc::swingv_t::kOff;
stdAc::swingh_t swingh; stdAc::swingh_t swingh = stdAc::swingh_t::kOff;
bool quiet; bool quiet = false;
bool turbo; bool turbo = false;
bool econo; bool econo = false;
bool light; bool light = false;
bool filter; bool filter = false;
bool clean; bool clean = false;
bool beep; bool beep = false;
int16_t sleep; int16_t sleep = -1; // `-1` means off.
int16_t clock; int16_t clock = -1; // `-1` means not set.
}; };
}; // namespace stdAc }; // namespace stdAc
@ -172,10 +172,10 @@ enum sharp_ac_remote_model_t {
A903 = 3, // 820 too A903 = 3, // 820 too
}; };
/// TCL A/C model numbers /// TCL (& Teknopoint) A/C model numbers
enum tcl_ac_remote_model_t { enum tcl_ac_remote_model_t {
TAC09CHSD = 1, TAC09CHSD = 1,
GZ055BE1 = 2, GZ055BE1 = 2, // Also Teknopoint GZ01-BEJ0-000
}; };
/// Voltas A/C model numbers /// Voltas A/C model numbers
@ -196,6 +196,7 @@ enum lg_ac_remote_model_t {
AKB75215403, // (2) LG2 28-bit Protocol AKB75215403, // (2) LG2 28-bit Protocol
AKB74955603, // (3) LG2 28-bit Protocol variant AKB74955603, // (3) LG2 28-bit Protocol variant
AKB73757604, // (4) LG2 Variant of AKB74955603 AKB73757604, // (4) LG2 Variant of AKB74955603
LG6711A20083V, // (5) Same as GE6711AR2853M, but only SwingV toggle.
}; };
@ -592,6 +593,16 @@ class IRsend {
// different sizes // different sizes
const uint16_t repeat = kHitachiAcDefaultRepeat); const uint16_t repeat = kHitachiAcDefaultRepeat);
#endif // SEND_HITACHI_AC3 #endif // SEND_HITACHI_AC3
#if SEND_HITACHI_AC264
void sendHitachiAc264(const unsigned char data[],
const uint16_t nbytes = kHitachiAc264StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat);
#endif // SEND_HITACHI_AC264
#if SEND_HITACHI_AC296
void sendHitachiAc296(const unsigned char data[],
const uint16_t nbytes = kHitachiAc296StateLength,
const uint16_t repeat = kHitachiAcDefaultRepeat);
#endif // SEND_HITACHI_AC296
#if SEND_HITACHI_AC344 #if SEND_HITACHI_AC344
void sendHitachiAc344(const unsigned char data[], void sendHitachiAc344(const unsigned char data[],
const uint16_t nbytes = kHitachiAc344StateLength, const uint16_t nbytes = kHitachiAc344StateLength,
@ -755,6 +766,11 @@ class IRsend {
void sendKelon(const uint64_t data, const uint16_t nbits = kKelonBits, void sendKelon(const uint64_t data, const uint16_t nbits = kKelonBits,
const uint16_t repeat = kNoRepeat); const uint16_t repeat = kNoRepeat);
#endif // SEND_KELON #endif // SEND_KELON
#if SEND_KELON168
void sendKelon168(const unsigned char data[],
const uint16_t nbytes = kKelon168StateLength,
const uint16_t repeat = kNoRepeat);
#endif // SEND_KELON168
#if SEND_BOSE #if SEND_BOSE
void sendBose(const uint64_t data, const uint16_t nbits = kBoseBits, void sendBose(const uint64_t data, const uint16_t nbits = kBoseBits,
const uint16_t repeat = kNoRepeat); const uint16_t repeat = kNoRepeat);

View File

@ -251,6 +251,8 @@ IRTEXT_CONST_STRING(kGe6711ar2853mStr, D_STR_GE6711AR2853M); ///<
IRTEXT_CONST_STRING(kAkb75215403Str, D_STR_AKB75215403); ///< "AKB75215403" IRTEXT_CONST_STRING(kAkb75215403Str, D_STR_AKB75215403); ///< "AKB75215403"
IRTEXT_CONST_STRING(kAkb74955603Str, D_STR_AKB74955603); ///< "AKB74955603" IRTEXT_CONST_STRING(kAkb74955603Str, D_STR_AKB74955603); ///< "AKB74955603"
IRTEXT_CONST_STRING(kAkb73757604Str, D_STR_AKB73757604); ///< "AKB73757604" IRTEXT_CONST_STRING(kAkb73757604Str, D_STR_AKB73757604); ///< "AKB73757604"
IRTEXT_CONST_STRING(kLg6711a20083vStr, D_STR_LG6711A20083V); ///<
///< "LG6711A20083V"
IRTEXT_CONST_STRING(kKkg9ac1Str, D_STR_KKG9AC1); ///< "KKG9AC1" IRTEXT_CONST_STRING(kKkg9ac1Str, D_STR_KKG9AC1); ///< "KKG9AC1"
IRTEXT_CONST_STRING(kKkg29ac1Str, D_STR_KKG29AC1); ///< "KKG29AC1" IRTEXT_CONST_STRING(kKkg29ac1Str, D_STR_KKG29AC1); ///< "KKG29AC1"
IRTEXT_CONST_STRING(kLkeStr, D_STR_LKE); ///< "LKE" IRTEXT_CONST_STRING(kLkeStr, D_STR_LKE); ///< "LKE"
@ -391,6 +393,9 @@ IRTEXT_CONST_BLOB_DECL(kAllProtocolNamesStr) {
D_STR_RHOSS "\x0" D_STR_RHOSS "\x0"
D_STR_AIRTON "\x0" D_STR_AIRTON "\x0"
D_STR_COOLIX48 "\x0" D_STR_COOLIX48 "\x0"
D_STR_HITACHI_AC264 "\x0"
D_STR_KELON168 "\x0"
D_STR_HITACHI_AC296 "\x0"
///< New protocol strings should be added just above this line. ///< New protocol strings should be added just above this line.
"\x0" ///< This string requires double null termination. "\x0" ///< This string requires double null termination.
}; };

View File

@ -1,4 +1,4 @@
// Copyright 2019-2021 - David Conran (@crankyoldgit) // Copyright 2019-2022 - David Conran (@crankyoldgit)
// This header file is to be included in files **other than** 'IRtext.cpp'. // This header file is to be included in files **other than** 'IRtext.cpp'.
// //
// WARNING: Do not edit this file! This file is automatically generated by // WARNING: Do not edit this file! This file is automatically generated by
@ -33,6 +33,7 @@ extern IRTEXT_CONST_PTR(k8CHeatStr);
extern IRTEXT_CONST_PTR(kA705Str); extern IRTEXT_CONST_PTR(kA705Str);
extern IRTEXT_CONST_PTR(kA903Str); extern IRTEXT_CONST_PTR(kA903Str);
extern IRTEXT_CONST_PTR(kA907Str); extern IRTEXT_CONST_PTR(kA907Str);
extern IRTEXT_CONST_PTR(kAbsenseDetectStr);
extern IRTEXT_CONST_PTR(kAirFlowStr); extern IRTEXT_CONST_PTR(kAirFlowStr);
extern IRTEXT_CONST_PTR(kAkb73757604Str); extern IRTEXT_CONST_PTR(kAkb73757604Str);
extern IRTEXT_CONST_PTR(kAkb74955603Str); extern IRTEXT_CONST_PTR(kAkb74955603Str);
@ -74,6 +75,8 @@ extern IRTEXT_CONST_PTR(kDehumidifyStr);
extern IRTEXT_CONST_PTR(kDg11j104Str); extern IRTEXT_CONST_PTR(kDg11j104Str);
extern IRTEXT_CONST_PTR(kDg11j13aStr); extern IRTEXT_CONST_PTR(kDg11j13aStr);
extern IRTEXT_CONST_PTR(kDg11j191Str); extern IRTEXT_CONST_PTR(kDg11j191Str);
extern IRTEXT_CONST_PTR(kDirectIndirectModeStr);
extern IRTEXT_CONST_PTR(kDirectStr);
extern IRTEXT_CONST_PTR(kDisplayTempStr); extern IRTEXT_CONST_PTR(kDisplayTempStr);
extern IRTEXT_CONST_PTR(kDkeStr); extern IRTEXT_CONST_PTR(kDkeStr);
extern IRTEXT_CONST_PTR(kDownStr); extern IRTEXT_CONST_PTR(kDownStr);
@ -108,8 +111,10 @@ extern IRTEXT_CONST_PTR(kHourStr);
extern IRTEXT_CONST_PTR(kHumidStr); extern IRTEXT_CONST_PTR(kHumidStr);
extern IRTEXT_CONST_PTR(kIdStr); extern IRTEXT_CONST_PTR(kIdStr);
extern IRTEXT_CONST_PTR(kIFeelStr); extern IRTEXT_CONST_PTR(kIFeelStr);
extern IRTEXT_CONST_PTR(kIndirectStr);
extern IRTEXT_CONST_PTR(kInsideStr); extern IRTEXT_CONST_PTR(kInsideStr);
extern IRTEXT_CONST_PTR(kIonStr); extern IRTEXT_CONST_PTR(kIonStr);
extern IRTEXT_CONST_PTR(kISeeStr);
extern IRTEXT_CONST_PTR(kJkeStr); extern IRTEXT_CONST_PTR(kJkeStr);
extern IRTEXT_CONST_PTR(kKkg29ac1Str); extern IRTEXT_CONST_PTR(kKkg29ac1Str);
extern IRTEXT_CONST_PTR(kKkg9ac1Str); extern IRTEXT_CONST_PTR(kKkg9ac1Str);
@ -117,11 +122,12 @@ extern IRTEXT_CONST_PTR(kLastStr);
extern IRTEXT_CONST_PTR(kLeftMaxNoSpaceStr); extern IRTEXT_CONST_PTR(kLeftMaxNoSpaceStr);
extern IRTEXT_CONST_PTR(kLeftMaxStr); extern IRTEXT_CONST_PTR(kLeftMaxStr);
extern IRTEXT_CONST_PTR(kLeftStr); extern IRTEXT_CONST_PTR(kLeftStr);
extern IRTEXT_CONST_PTR(kLg6711a20083vStr);
extern IRTEXT_CONST_PTR(kLightStr); extern IRTEXT_CONST_PTR(kLightStr);
extern IRTEXT_CONST_PTR(kLightToggleStr); extern IRTEXT_CONST_PTR(kLightToggleStr);
extern IRTEXT_CONST_PTR(kLkeStr); extern IRTEXT_CONST_PTR(kLkeStr);
extern IRTEXT_CONST_PTR(kLoStr);
extern IRTEXT_CONST_PTR(kLockStr); extern IRTEXT_CONST_PTR(kLockStr);
extern IRTEXT_CONST_PTR(kLoStr);
extern IRTEXT_CONST_PTR(kLoudStr); extern IRTEXT_CONST_PTR(kLoudStr);
extern IRTEXT_CONST_PTR(kLowerStr); extern IRTEXT_CONST_PTR(kLowerStr);
extern IRTEXT_CONST_PTR(kLowestStr); extern IRTEXT_CONST_PTR(kLowestStr);
@ -231,11 +237,5 @@ extern IRTEXT_CONST_PTR(kYbofbStr);
extern IRTEXT_CONST_PTR(kYesStr); extern IRTEXT_CONST_PTR(kYesStr);
extern IRTEXT_CONST_PTR(kZoneFollowStr); extern IRTEXT_CONST_PTR(kZoneFollowStr);
extern IRTEXT_CONST_PTR(kAllProtocolNamesStr); extern IRTEXT_CONST_PTR(kAllProtocolNamesStr);
extern IRTEXT_CONST_PTR(kISeeStr);
extern IRTEXT_CONST_PTR(kEcocoolStr);
extern IRTEXT_CONST_PTR(kAbsenseDetectStr);
extern IRTEXT_CONST_PTR(kDirectIndirectModeStr);
extern IRTEXT_CONST_PTR(kDirectStr);
extern IRTEXT_CONST_PTR(kIndirectStr);
#endif // IRTEXT_H_ #endif // IRTEXT_H_

View File

@ -190,8 +190,11 @@ bool hasACState(const decode_type_t protocol) {
case HITACHI_AC1: case HITACHI_AC1:
case HITACHI_AC2: case HITACHI_AC2:
case HITACHI_AC3: case HITACHI_AC3:
case HITACHI_AC264:
case HITACHI_AC296:
case HITACHI_AC344: case HITACHI_AC344:
case HITACHI_AC424: case HITACHI_AC424:
case KELON168:
case KELVINATOR: case KELVINATOR:
case MIRAGE: case MIRAGE:
case MITSUBISHI136: case MITSUBISHI136:
@ -634,6 +637,7 @@ namespace irutils {
case lg_ac_remote_model_t::AKB75215403: return kAkb75215403Str; case lg_ac_remote_model_t::AKB75215403: return kAkb75215403Str;
case lg_ac_remote_model_t::AKB74955603: return kAkb74955603Str; case lg_ac_remote_model_t::AKB74955603: return kAkb74955603Str;
case lg_ac_remote_model_t::AKB73757604: return kAkb73757604Str; case lg_ac_remote_model_t::AKB73757604: return kAkb73757604Str;
case lg_ac_remote_model_t::LG6711A20083V: return kLg6711a20083vStr;
default: return kUnknownStr; default: return kUnknownStr;
} }
break; break;

View File

@ -317,7 +317,7 @@ bool IRAirtonAc::getHealth(void) const { return _.Health; }
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRAirtonAc::toCommon(void) const { stdAc::state_t IRAirtonAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::AIRTON; result.protocol = decode_type_t::AIRTON;
result.power = getPower(); result.power = getPower();
result.mode = toCommonMode(getMode()); result.mode = toCommonMode(getMode());

View File

@ -238,7 +238,7 @@ uint8_t IRAirwellAc::getTemp(void) const {
/// @param[in] prev Ptr to the previous state if required. /// @param[in] prev Ptr to the previous state if required.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRAirwellAc::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRAirwellAc::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
// Start with the previous state if given it. // Start with the previous state if given it.
if (prev != NULL) { if (prev != NULL) {
result = *prev; result = *prev;

View File

@ -314,7 +314,7 @@ stdAc::fanspeed_t IRAmcorAc::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRAmcorAc::toCommon(void) const { stdAc::state_t IRAmcorAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::AMCOR; result.protocol = decode_type_t::AMCOR;
result.power = getPower(); result.power = getPower();
result.mode = toCommonMode(_.Mode); result.mode = toCommonMode(_.Mode);

View File

@ -344,7 +344,7 @@ stdAc::fanspeed_t IRArgoAC::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRArgoAC::toCommon(void) const { stdAc::state_t IRArgoAC::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::ARGO; result.protocol = decode_type_t::ARGO;
result.power = _.Power; result.power = _.Power;
result.mode = toCommonMode(_.Mode); result.mode = toCommonMode(_.Mode);

View File

@ -511,7 +511,7 @@ String IRCarrierAc64::toString(void) const {
/// Convert the A/C state to it's common stdAc::state_t equivalent. /// Convert the A/C state to it's common stdAc::state_t equivalent.
/// @return A stdAc::state_t state. /// @return A stdAc::state_t state.
stdAc::state_t IRCarrierAc64::toCommon(void) const { stdAc::state_t IRCarrierAc64::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::CARRIER_AC64; result.protocol = decode_type_t::CARRIER_AC64;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;

View File

@ -32,7 +32,7 @@ const uint16_t kCoolixHdrSpaceTicks = 16;
const uint16_t kCoolixHdrSpace = kCoolixHdrSpaceTicks * kCoolixTick; // 4416us const uint16_t kCoolixHdrSpace = kCoolixHdrSpaceTicks * kCoolixTick; // 4416us
const uint16_t kCoolixMinGapTicks = kCoolixHdrMarkTicks + kCoolixZeroSpaceTicks; const uint16_t kCoolixMinGapTicks = kCoolixHdrMarkTicks + kCoolixZeroSpaceTicks;
const uint16_t kCoolixMinGap = kCoolixMinGapTicks * kCoolixTick; // 5244us const uint16_t kCoolixMinGap = kCoolixMinGapTicks * kCoolixTick; // 5244us
const uint8_t kCoolix48ExtraTolerance = 5; // Percent const uint8_t kCoolixExtraTolerance = 5; // Percent
using irutils::addBoolToString; using irutils::addBoolToString;
using irutils::addIntToString; using irutils::addIntToString;
@ -496,7 +496,7 @@ stdAc::fanspeed_t IRCoolixAC::toCommonFanSpeed(const uint8_t speed) {
/// @param[in] prev Ptr to the previous state if required. /// @param[in] prev Ptr to the previous state if required.
/// @return A stdAc::state_t state. /// @return A stdAc::state_t state.
stdAc::state_t IRCoolixAC::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRCoolixAC::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
// Start with the previous state if given it. // Start with the previous state if given it.
if (prev != NULL) { if (prev != NULL) {
result = *prev; result = *prev;
@ -648,41 +648,39 @@ bool IRrecv::decodeCOOLIX(decode_results *results, uint16_t offset,
return false; // We can't possibly capture a Coolix packet that big. return false; // We can't possibly capture a Coolix packet that big.
// Header // Header
if (!matchMark(results->rawbuf[offset], kCoolixHdrMark)) return false; if (!matchMark(results->rawbuf[offset++], kCoolixHdrMark)) return false;
// Calculate how long the common tick time is based on the header mark. if (!matchSpace(results->rawbuf[offset++], kCoolixHdrSpace)) return false;
uint32_t m_tick = results->rawbuf[offset++] * kRawTick / kCoolixHdrMarkTicks;
if (!matchSpace(results->rawbuf[offset], kCoolixHdrSpace)) return false;
// Calculate how long the common tick time is based on the header space.
uint32_t s_tick = results->rawbuf[offset++] * kRawTick / kCoolixHdrSpaceTicks;
// Data // Data
// Twice as many bits as there are normal plus inverted bits. // Twice as many bits as there are normal plus inverted bits.
for (uint16_t i = 0; i < nbits * 2; i++, offset++) { for (uint16_t i = 0; i < nbits * 2; i += 8) {
bool flip = (i / 8) % 2; const bool flip = (i / 8) % 2;
if (!matchMark(results->rawbuf[offset++], kCoolixBitMarkTicks * m_tick)) uint64_t result = 0;
return false; // Read the next byte of data.
if (matchSpace(results->rawbuf[offset], kCoolixOneSpaceTicks * s_tick)) { const uint16_t used = matchGeneric(results->rawbuf + offset, &result,
if (flip) results->rawlen - offset, 8,
inverted = (inverted << 1) | 1; 0, 0, // No Header
else kCoolixBitMark, kCoolixOneSpace, // Data
data = (data << 1) | 1; kCoolixBitMark, kCoolixZeroSpace,
} else if (matchSpace(results->rawbuf[offset], 0, 0, // No Footer
kCoolixZeroSpaceTicks * s_tick)) { false,
if (flip) _tolerance + kCoolixExtraTolerance,
inverted <<= 1; 0, true);
else if (!used) return false; // Didn't match a bytes worth of data.
data <<= 1; offset += used;
if (flip) { // The inverted byte.
inverted <<= 8;
inverted |= result;
} else { } else {
return false; data <<= 8;
data |= result;
} }
} }
// Footer // Footer
if (!matchMark(results->rawbuf[offset++], kCoolixBitMarkTicks * m_tick)) if (!matchMark(results->rawbuf[offset++], kCoolixBitMark)) return false;
return false;
if (offset < results->rawlen && if (offset < results->rawlen &&
!matchAtLeast(results->rawbuf[offset], kCoolixMinGapTicks * s_tick)) !matchAtLeast(results->rawbuf[offset], kCoolixMinGap)) return false;
return false;
// Compliance // Compliance
uint64_t orig = data; // Save a copy of the data. uint64_t orig = data; // Save a copy of the data.
@ -744,7 +742,7 @@ bool IRrecv::decodeCoolix48(decode_results *results, uint16_t offset,
kCoolixBitMark, kCoolixOneSpace, kCoolixBitMark, kCoolixOneSpace,
kCoolixBitMark, kCoolixZeroSpace, kCoolixBitMark, kCoolixZeroSpace,
kCoolixBitMark, kCoolixMinGap, kCoolixBitMark, kCoolixMinGap,
true, _tolerance + kCoolix48ExtraTolerance, 0, true)) true, _tolerance + kCoolixExtraTolerance, 0, true))
return false; return false;
// Success // Success

View File

@ -550,7 +550,7 @@ String IRCoronaAc::toString(void) const {
/// Convert the A/C state to it's common stdAc::state_t equivalent. /// Convert the A/C state to it's common stdAc::state_t equivalent.
/// @return A stdAc::state_t state. /// @return A stdAc::state_t state.
stdAc::state_t IRCoronaAc::toCommon() const { stdAc::state_t IRCoronaAc::toCommon() const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::CORONA_AC; result.protocol = decode_type_t::CORONA_AC;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;

View File

@ -529,7 +529,7 @@ stdAc::fanspeed_t IRDaikinESP::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRDaikinESP::toCommon(void) const { stdAc::state_t IRDaikinESP::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::DAIKIN; result.protocol = decode_type_t::DAIKIN;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;
@ -1199,7 +1199,7 @@ stdAc::swingh_t IRDaikin2::toCommonSwingH(const uint8_t setting) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRDaikin2::toCommon(void) const { stdAc::state_t IRDaikin2::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::DAIKIN2; result.protocol = decode_type_t::DAIKIN2;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = getPower(); result.power = getPower();
@ -1621,7 +1621,7 @@ bool IRDaikin216::getPowerful(void) const { return _.Powerful; }
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRDaikin216::toCommon(void) const { stdAc::state_t IRDaikin216::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::DAIKIN216; result.protocol = decode_type_t::DAIKIN216;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;
@ -1971,7 +1971,7 @@ stdAc::swingv_t IRDaikin160::toCommonSwingV(const uint8_t setting) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRDaikin160::toCommon(void) const { stdAc::state_t IRDaikin160::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::DAIKIN160; result.protocol = decode_type_t::DAIKIN160;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;
@ -2362,7 +2362,7 @@ stdAc::fanspeed_t IRDaikin176::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRDaikin176::toCommon(void) const { stdAc::state_t IRDaikin176::toCommon(void) const {
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 = _.Power; result.power = _.Power;
@ -2883,7 +2883,7 @@ String IRDaikin128::toString(void) const {
/// @param[in] prev Ptr to a previous state. /// @param[in] prev Ptr to a previous state.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRDaikin128::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRDaikin128::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
if (prev != NULL) result = *prev; if (prev != NULL) result = *prev;
result.protocol = decode_type_t::DAIKIN128; result.protocol = decode_type_t::DAIKIN128;
result.model = -1; // No models used. result.model = -1; // No models used.
@ -3285,7 +3285,7 @@ bool IRDaikin152::getComfort(void) const { return _.Comfort; }
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRDaikin152::toCommon(void) const { stdAc::state_t IRDaikin152::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::DAIKIN152; result.protocol = decode_type_t::DAIKIN152;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;
@ -3710,7 +3710,7 @@ String IRDaikin64::toString(void) const {
/// @param[in] prev Ptr to a previous state. /// @param[in] prev Ptr to a previous state.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRDaikin64::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRDaikin64::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
if (prev != NULL) result = *prev; if (prev != NULL) result = *prev;
result.protocol = decode_type_t::DAIKIN64; result.protocol = decode_type_t::DAIKIN64;
result.model = -1; // No models used. result.model = -1; // No models used.

View File

@ -34,9 +34,9 @@
// Brand: Daikin, Model: BRC4C153 remote (DAIKIN176) // Brand: Daikin, Model: BRC4C153 remote (DAIKIN176)
// Brand: Daikin, Model: FFQ35B8V1B A/C (DAIKIN176) // Brand: Daikin, Model: FFQ35B8V1B A/C (DAIKIN176)
// Brand: Daikin, Model: BRC4C151 remote (DAIKIN176) // Brand: Daikin, Model: BRC4C151 remote (DAIKIN176)
// Brand: Daikin, Model: 17 Series A/C (DAIKIN128) // Brand: Daikin, Model: 17 Series FTXB09AXVJU A/C (DAIKIN128)
// Brand: Daikin, Model: FTXB12AXVJU A/C (DAIKIN128) // Brand: Daikin, Model: 17 Series FTXB12AXVJU A/C (DAIKIN128)
// Brand: Daikin, Model: FTXB09AXVJU A/C (DAIKIN128) // Brand: Daikin, Model: 17 Series FTXB24AXVJU A/C (NOT SUPPORTED)
// Brand: Daikin, Model: BRC52B63 remote (DAIKIN128) // Brand: Daikin, Model: BRC52B63 remote (DAIKIN128)
// Brand: Daikin, Model: ARC480A5 remote (DAIKIN152) // Brand: Daikin, Model: ARC480A5 remote (DAIKIN152)
// Brand: Daikin, Model: FFN-C/FCN-F Series A/C (DAIKIN64) // Brand: Daikin, Model: FFN-C/FCN-F Series A/C (DAIKIN64)

View File

@ -421,7 +421,7 @@ uint16_t IRDelonghiAc::getOffTimer(void) const {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRDelonghiAc::toCommon(void) const { stdAc::state_t IRDelonghiAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::DELONGHI_AC; result.protocol = decode_type_t::DELONGHI_AC;
result.power = _.Power; result.power = _.Power;
// result.mode = toCommonMode(getMode()); // result.mode = toCommonMode(getMode());

View File

@ -359,7 +359,7 @@ void IREcoclimAc::disableOffTimer(void) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IREcoclimAc::toCommon(void) const { stdAc::state_t IREcoclimAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::ECOCLIM; result.protocol = decode_type_t::ECOCLIM;
result.power = _.Power; result.power = _.Power;
result.mode = toCommonMode(getMode()); result.mode = toCommonMode(getMode());

View File

@ -359,7 +359,7 @@ uint8_t IRElectraAc::getSensorTemp(void) const {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRElectraAc::toCommon(void) const { stdAc::state_t IRElectraAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::ELECTRA_AC; result.protocol = decode_type_t::ELECTRA_AC;
result.power = _.Power; result.power = _.Power;
result.mode = toCommonMode(_.Mode); result.mode = toCommonMode(_.Mode);

View File

@ -13,6 +13,7 @@
// Brand: Subtropic, Model: YKR-H/102E remote // Brand: Subtropic, Model: YKR-H/102E remote
// Brand: Centek, Model: SCT-65Q09 A/C // Brand: Centek, Model: SCT-65Q09 A/C
// Brand: Centek, Model: YKR-P/002E remote // Brand: Centek, Model: YKR-P/002E remote
// Brand: AEG, Model: Chillflex Pro AXP26U338CW A/C
#ifndef IR_ELECTRA_H_ #ifndef IR_ELECTRA_H_
#define IR_ELECTRA_H_ #define IR_ELECTRA_H_

View File

@ -776,7 +776,7 @@ stdAc::fanspeed_t IRFujitsuAC::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRFujitsuAC::toCommon(void) const { stdAc::state_t IRFujitsuAC::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::FUJITSU_AC; result.protocol = decode_type_t::FUJITSU_AC;
result.model = _model; result.model = _model;
result.power = getPower(); result.power = getPower();

View File

@ -311,7 +311,7 @@ stdAc::fanspeed_t IRGoodweatherAc::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRGoodweatherAc::toCommon(void) const { stdAc::state_t IRGoodweatherAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::GOODWEATHER; result.protocol = decode_type_t::GOODWEATHER;
result.power = _.Power; result.power = _.Power;
result.mode = toCommonMode(_.Mode); result.mode = toCommonMode(_.Mode);

View File

@ -575,7 +575,7 @@ stdAc::swingh_t IRGreeAC::toCommonSwingH(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
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 = _model; result.model = _model;
result.power = _.Power; result.power = _.Power;

View File

@ -426,7 +426,7 @@ stdAc::swingv_t IRHaierAC::toCommonSwingV(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRHaierAC::toCommon(void) const { stdAc::state_t IRHaierAC::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::HAIER_AC; result.protocol = decode_type_t::HAIER_AC;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = true; result.power = true;
@ -1127,7 +1127,7 @@ stdAc::swingh_t IRHaierAC176::toCommonSwingH(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRHaierAC176::toCommon(void) const { stdAc::state_t IRHaierAC176::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::HAIER_AC_YRW02; result.protocol = decode_type_t::HAIER_AC_YRW02;
result.model = getModel(); result.model = getModel();
result.power = _.Power; result.power = _.Power;

View File

@ -7,6 +7,7 @@
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1757
#include "ir_Hitachi.h" #include "ir_Hitachi.h"
#include <algorithm> #include <algorithm>
@ -56,7 +57,8 @@ using irutils::checkInvertedBytePairs;
using irutils::invertBytePairs; using irutils::invertBytePairs;
using irutils::minsToString; using irutils::minsToString;
#if (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC344) #if (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC264 || \
SEND_HITACHI_AC344)
/// Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC) /// Send a Hitachi 28-byte/224-bit A/C formatted message. (HITACHI_AC)
/// Status: STABLE / Working. /// Status: STABLE / Working.
/// @param[in] data The message to be sent. /// @param[in] data The message to be sent.
@ -68,13 +70,21 @@ void IRsend::sendHitachiAC(const unsigned char data[], const uint16_t nbytes,
if (nbytes < kHitachiAcStateLength) if (nbytes < kHitachiAcStateLength)
return; // Not enough bytes to send a proper message. return; // Not enough bytes to send a proper message.
const bool MSBfirst = (nbytes == kHitachiAc344StateLength) ? false : true; bool MSBfirst = true;
switch (nbytes) {
case kHitachiAc264StateLength:
case kHitachiAc296StateLength:
case kHitachiAc344StateLength:
MSBfirst = false;
}
sendGeneric(kHitachiAcHdrMark, kHitachiAcHdrSpace, kHitachiAcBitMark, sendGeneric(kHitachiAcHdrMark, kHitachiAcHdrSpace, kHitachiAcBitMark,
kHitachiAcOneSpace, kHitachiAcBitMark, kHitachiAcZeroSpace, kHitachiAcOneSpace, kHitachiAcBitMark, kHitachiAcZeroSpace,
kHitachiAcBitMark, kHitachiAcMinGap, data, nbytes, 38, MSBfirst, kHitachiAcBitMark, kHitachiAcMinGap, data, nbytes, 38, MSBfirst,
repeat, 50); repeat, 50);
} }
#endif // (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC344) #endif // (SEND_HITACHI_AC || SEND_HITACHI_AC2 || SEND_HITACHI_AC264 ||
// SEND_HITACHI_AC344)
#if SEND_HITACHI_AC1 #if SEND_HITACHI_AC1
/// Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1) /// Send a Hitachi 13 byte/224-bit A/C formatted message. (HITACHI_AC1)
@ -82,7 +92,7 @@ void IRsend::sendHitachiAC(const unsigned char data[], const uint16_t nbytes,
/// @param[in] data The message to be sent. /// @param[in] data The message to be sent.
/// @param[in] nbytes The number of bytes of message to be sent. /// @param[in] nbytes The number of bytes of message to be sent.
/// @param[in] repeat The number of times the command is to be repeated. /// @param[in] repeat The number of times the command is to be repeated.
/// @note Basically the same as sendHitatchiAC() except different size & header. /// @note Basically the same as sendHitachiAC() except different size & header.
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453
void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes, void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) { const uint16_t repeat) {
@ -97,7 +107,7 @@ void IRsend::sendHitachiAC1(const unsigned char data[], const uint16_t nbytes,
#if SEND_HITACHI_AC2 #if SEND_HITACHI_AC2
/// Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2) /// Send a Hitachi 53 byte/424-bit A/C formatted message. (HITACHI_AC2)
/// Basically the same as sendHitatchiAC() except different size. /// Basically the same as sendHitachiAC() except different size.
/// Status: STABLE / Expected to work. /// Status: STABLE / Expected to work.
/// @param[in] data The message to be sent. /// @param[in] data The message to be sent.
/// @param[in] nbytes The number of bytes of message to be sent. /// @param[in] nbytes The number of bytes of message to be sent.
@ -112,7 +122,7 @@ void IRsend::sendHitachiAC2(const unsigned char data[], const uint16_t nbytes,
#if SEND_HITACHI_AC344 #if SEND_HITACHI_AC344
/// Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344) /// Send a Hitachi A/C 43-byte/344-bit message. (HITACHI_AC344)
/// Basically the same as sendHitatchiAC() except different size. /// Basically the same as sendHitachiAC() except different size.
/// Status: Beta / Probably works. /// Status: Beta / Probably works.
/// @param[in] data An array of bytes containing the IR command. /// @param[in] data An array of bytes containing the IR command.
/// @param[in] nbytes Nr. of bytes of data in the array. /// @param[in] nbytes Nr. of bytes of data in the array.
@ -373,7 +383,7 @@ stdAc::fanspeed_t IRHitachiAc::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRHitachiAc::toCommon(void) const { stdAc::state_t IRHitachiAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::HITACHI_AC; result.protocol = decode_type_t::HITACHI_AC;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;
@ -773,7 +783,7 @@ stdAc::fanspeed_t IRHitachiAc1::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRHitachiAc1::toCommon(void) const { stdAc::state_t IRHitachiAc1::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::HITACHI_AC1; result.protocol = decode_type_t::HITACHI_AC1;
result.model = getModel(); result.model = getModel();
result.power = _.Power; result.power = _.Power;
@ -827,7 +837,7 @@ String IRHitachiAc1::toString(void) const {
} }
#if (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || \ #if (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || \
DECODE_HITACHI_AC344) DECODE_HITACHI_AC344 || DECODE_HITACHI_AC264)
/// Decode the supplied Hitachi A/C message. /// Decode the supplied Hitachi A/C message.
/// Status: STABLE / Expected to work. /// Status: STABLE / Expected to work.
/// @param[in,out] results Ptr to the data to decode & where to store the result /// @param[in,out] results Ptr to the data to decode & where to store the result
@ -835,7 +845,7 @@ String IRHitachiAc1::toString(void) const {
/// raw data. Typically/Defaults to kStartOffset. /// raw data. Typically/Defaults to kStartOffset.
/// @param[in] nbits The number of data bits to expect. /// @param[in] nbits The number of data bits to expect.
/// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits, /// Typically kHitachiAcBits, kHitachiAc1Bits, kHitachiAc2Bits,
/// kHitachiAc344Bits /// kHitachiAc344Bits, kHitachiAc264Bits
/// @param[in] strict Flag indicating if we should perform strict matching. /// @param[in] strict Flag indicating if we should perform strict matching.
/// @param[in] MSBfirst Is the data per byte stored in MSB First (true) or /// @param[in] MSBfirst Is the data per byte stored in MSB First (true) or
/// LSB First order(false)? /// LSB First order(false)?
@ -843,6 +853,7 @@ String IRHitachiAc1::toString(void) const {
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/417
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/453
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1729
bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset, bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict, const uint16_t nbits, const bool strict,
const bool MSBfirst) { const bool MSBfirst) {
@ -853,6 +864,7 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset,
case kHitachiAcBits: case kHitachiAcBits:
case kHitachiAc1Bits: case kHitachiAc1Bits:
case kHitachiAc2Bits: case kHitachiAc2Bits:
case kHitachiAc264Bits:
case kHitachiAc344Bits: case kHitachiAc344Bits:
break; // Okay to continue. break; // Okay to continue.
default: default:
@ -879,16 +891,20 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset,
// Compliance // Compliance
if (strict) { if (strict) {
if (nbits / 8 == kHitachiAcStateLength && const uint16_t nbytes = nbits / 8;
!IRHitachiAc::validChecksum(results->state, kHitachiAcStateLength)) switch (nbytes) {
return false; case kHitachiAcStateLength:
if (nbits / 8 == kHitachiAc1StateLength && if (!IRHitachiAc::validChecksum(results->state, nbytes)) return false;
!IRHitachiAc1::validChecksum(results->state, kHitachiAc1StateLength)) break;
return false; case kHitachiAc1StateLength:
if (nbits / 8 == kHitachiAc344StateLength && if (!IRHitachiAc1::validChecksum(results->state, nbytes)) return false;
!IRHitachiAc3::hasInvertedStates(results->state, break;
kHitachiAc344StateLength)) case kHitachiAc264StateLength:
return false; case kHitachiAc344StateLength:
if (!IRHitachiAc3::hasInvertedStates(results->state, nbytes))
return false;
break;
}
} }
// Success // Success
@ -899,6 +915,9 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset,
case kHitachiAc2Bits: case kHitachiAc2Bits:
results->decode_type = decode_type_t::HITACHI_AC2; results->decode_type = decode_type_t::HITACHI_AC2;
break; break;
case kHitachiAc264Bits:
results->decode_type = decode_type_t::HITACHI_AC264;
break;
case kHitachiAc344Bits: case kHitachiAc344Bits:
results->decode_type = decode_type_t::HITACHI_AC344; results->decode_type = decode_type_t::HITACHI_AC344;
break; break;
@ -913,7 +932,7 @@ bool IRrecv::decodeHitachiAC(decode_results *results, uint16_t offset,
return true; return true;
} }
#endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 || #endif // (DECODE_HITACHI_AC || DECODE_HITACHI_AC1 || DECODE_HITACHI_AC2 ||
// DECODE_HITACHI_AC344) // DECODE_HITACHI_AC344 || DECODE_HITACHI_AC264)
#if SEND_HITACHI_AC424 #if SEND_HITACHI_AC424
/// Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424) /// Send a Hitachi 53-byte/424-bit A/C formatted message. (HITACHI_AC424)
@ -1008,6 +1027,7 @@ void IRHitachiAc424::stateReset(void) {
_.raw[3] = 0x40; _.raw[3] = 0x40;
_.raw[5] = 0xFF; _.raw[5] = 0xFF;
_.raw[7] = 0xCC; _.raw[7] = 0xCC;
_.raw[27] = 0xE1;
_.raw[33] = 0x80; _.raw[33] = 0x80;
_.raw[35] = 0x03; _.raw[35] = 0x03;
_.raw[37] = 0x01; _.raw[37] = 0x01;
@ -1055,15 +1075,13 @@ void IRHitachiAc424::send(const uint16_t repeat) {
/// Get the value of the current power setting. /// Get the value of the current power setting.
/// @return true, the setting is on. false, the setting is off. /// @return true, the setting is on. false, the setting is off.
bool IRHitachiAc424::getPower(void) const { bool IRHitachiAc424::getPower(void) const { return _.Power; }
return _.Power == kHitachiAc424PowerOn;
}
/// Change the power setting. /// Change the power setting.
/// @param[in] on true, the setting is on. false, the setting is off. /// @param[in] on true, the setting is on. false, the setting is off.
void IRHitachiAc424::setPower(const bool on) { void IRHitachiAc424::setPower(const bool on) {
_.Power = on;
setButton(kHitachiAc424ButtonPowerMode); setButton(kHitachiAc424ButtonPowerMode);
_.Power = (on ? kHitachiAc424PowerOn : kHitachiAc424PowerOff);
} }
/// Change the power setting to On. /// Change the power setting to On.
@ -1203,7 +1221,7 @@ uint8_t IRHitachiAc424::convertMode(const stdAc::opmode_t mode) {
/// Convert a stdAc::fanspeed_t enum into it's native speed. /// Convert a stdAc::fanspeed_t enum into it's native speed.
/// @param[in] speed The enum to be converted. /// @param[in] speed The enum to be converted.
/// @return The native equivalent of the enum. /// @return The native equivalent of the enum.
uint8_t IRHitachiAc424::convertFan(const stdAc::fanspeed_t speed) { uint8_t IRHitachiAc424::convertFan(const stdAc::fanspeed_t speed) const {
switch (speed) { switch (speed) {
case stdAc::fanspeed_t::kMin: return kHitachiAc424FanMin; case stdAc::fanspeed_t::kMin: return kHitachiAc424FanMin;
case stdAc::fanspeed_t::kLow: return kHitachiAc424FanLow; case stdAc::fanspeed_t::kLow: return kHitachiAc424FanLow;
@ -1230,7 +1248,7 @@ stdAc::opmode_t IRHitachiAc424::toCommonMode(const uint8_t mode) {
/// Convert a native fan speed into its stdAc equivalent. /// Convert a native fan speed into its stdAc equivalent.
/// @param[in] speed The native setting to be converted. /// @param[in] speed The native setting to be converted.
/// @return The stdAc equivalent of the native setting. /// @return The stdAc equivalent of the native setting.
stdAc::fanspeed_t IRHitachiAc424::toCommonFanSpeed(const uint8_t speed) { stdAc::fanspeed_t IRHitachiAc424::toCommonFanSpeed(const uint8_t speed) const {
switch (speed) { switch (speed) {
case kHitachiAc424FanMax: return stdAc::fanspeed_t::kMax; case kHitachiAc424FanMax: return stdAc::fanspeed_t::kMax;
case kHitachiAc424FanHigh: return stdAc::fanspeed_t::kHigh; case kHitachiAc424FanHigh: return stdAc::fanspeed_t::kHigh;
@ -1244,7 +1262,7 @@ stdAc::fanspeed_t IRHitachiAc424::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRHitachiAc424::toCommon(void) const { stdAc::state_t IRHitachiAc424::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::HITACHI_AC424; result.protocol = decode_type_t::HITACHI_AC424;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = getPower(); result.power = getPower();
@ -1578,3 +1596,401 @@ String IRHitachiAc344::toString(void) const {
result += ')'; result += ')';
return result; return result;
} }
#if SEND_HITACHI_AC264
/// Send a Hitachi 33-byte/264-bit A/C message (HITACHI_AC264)
/// Basically the same as sendHitachiAC() except different size.
/// Status: STABLE / Reported as working.
/// @param[in] data An array of bytes containing the IR command.
/// @param[in] nbytes Nr. of bytes of data in the array.
/// @param[in] repeat Nr. of times the message is to be repeated. (Default = 0).
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1729
void IRsend::sendHitachiAc264(const unsigned char data[], const uint16_t nbytes,
const uint16_t repeat) {
if (nbytes < kHitachiAc264StateLength)
return; // Not enough bytes to send a proper message.
sendHitachiAC(data, nbytes, repeat);
}
#endif // SEND_HITACHI_AC264
// Class constructor for handling detailed Hitachi_AC344 43 byte A/C messages.
/// @param[in] pin GPIO to be used when sending.
/// @param[in] inverted Is the output signal to be inverted?
/// @param[in] use_modulation Is frequency modulation to be used?
IRHitachiAc264::IRHitachiAc264(const uint16_t pin, const bool inverted,
const bool use_modulation)
: IRHitachiAc424(pin, inverted, use_modulation) { stateReset(); }
/// Reset the internal state to auto fan, cooling, 23° Celsius
void IRHitachiAc264::stateReset(void) {
IRHitachiAc424::stateReset();
_.raw[9] = 0x92;
_.raw[27] = 0xC1;
}
#if SEND_HITACHI_AC264
/// Create and send the IR message to the A/C.
/// @param[in] repeat Nr. of times to repeat the message.
void IRHitachiAc264::send(const uint16_t repeat) {
_irsend.sendHitachiAc264(getRaw(), kHitachiAc264StateLength, repeat);
}
#endif // SEND_HITACHI_AC264
/// Set the internal state from a valid code for this protocol.
/// @param[in] new_code A valid code for this protocol.
/// @param[in] length Size (in bytes) of the code for this protocol.
void IRHitachiAc264::setRaw(const uint8_t new_code[], const uint16_t length) {
memcpy(_.raw, new_code, std::min(length, kHitachiAc264StateLength));
}
/// Set the speed of the fan.
/// @param[in] speed The desired setting.
void IRHitachiAc264::setFan(const uint8_t speed) {
switch (speed) {
case kHitachiAc264FanMin:
case kHitachiAc264FanMedium:
case kHitachiAc264FanHigh:
case kHitachiAc264FanAuto:
_.Fan = speed;
break;
default:
setFan(kHitachiAc264FanAuto);
}
}
/// Convert a stdAc::fanspeed_t enum into it's native speed.
/// @param[in] speed The enum to be converted.
/// @return The native equivalent of the enum.
uint8_t IRHitachiAc264::convertFan(const stdAc::fanspeed_t speed) const {
switch (speed) {
case stdAc::fanspeed_t::kMin:
case stdAc::fanspeed_t::kLow: return kHitachiAc264FanMin;
case stdAc::fanspeed_t::kMedium: return kHitachiAc264FanMedium;
case stdAc::fanspeed_t::kHigh:
case stdAc::fanspeed_t::kMax: return kHitachiAc424FanHigh;
default: return kHitachiAc424FanAuto;
}
}
/// Convert a native fan speed into its stdAc equivalent.
/// @param[in] speed The native setting to be converted.
/// @return The stdAc equivalent of the native setting.
stdAc::fanspeed_t IRHitachiAc264::toCommonFanSpeed(const uint8_t speed) const {
switch (speed) {
case kHitachiAc264FanHigh: return stdAc::fanspeed_t::kHigh;
case kHitachiAc264FanMedium: return stdAc::fanspeed_t::kMedium;
case kHitachiAc264FanMin: return stdAc::fanspeed_t::kMin;
default: return stdAc::fanspeed_t::kAuto;
}
}
/// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings.
stdAc::state_t IRHitachiAc264::toCommon(void) const {
stdAc::state_t result = IRHitachiAc424::toCommon();
result.protocol = decode_type_t::HITACHI_AC264;
result.swingv = stdAc::swingv_t::kOff;
return result;
}
/// Convert the internal state into a human readable string.
/// @return A string containing the settings in human-readable form.
String IRHitachiAc264::toString(void) const {
String result;
result.reserve(120); // Reserve some heap for the string to reduce fragging.
result += _toString();
return result;
}
#if DECODE_HITACHI_AC264
// For Decoding HITACHI_AC264, see `decodeHitachiAC`
#endif // DECODE_HITACHI_AC264
#if SEND_HITACHI_AC296
/// Send a HitachiAc 37-byte/296-bit A/C message (HITACHI_AC296)
/// Status: STABLE / Working on a real device.
/// @param[in] data containing the IR command.
/// @param[in] nbytes Nr. of bytes to send. usually kHitachiAc296StateLength
/// @param[in] repeat Nr. of times the message is to be repeated.
void IRsend::sendHitachiAc296(const unsigned char data[],
const uint16_t nbytes,
const uint16_t repeat) {
if (nbytes < kHitachiAc296StateLength)
return; // Not enough bytes to send a proper message.
sendHitachiAC(data, nbytes, repeat);
}
#endif // SEND_HITACHIAC296
// Class constructor for handling detailed Hitachi_AC296 37 byte A/C messages.
/// @param[in] pin GPIO to be used when sending.
/// @param[in] inverted Is the output signal to be inverted?
/// @param[in] use_modulation Is frequency modulation to be used?
IRHitachiAc296::IRHitachiAc296(const uint16_t pin, const bool inverted,
const bool use_modulation)
: _irsend(pin, inverted, use_modulation) { stateReset(); }
/// Reset the internal state to auto fan, heating, & 24° Celsius
void IRHitachiAc296::stateReset(void) {
// Header
_.raw[0] = 0x01;
_.raw[1] = 0x10;
_.raw[2] = 0x00;
// Every next byte is a parity byte
_.raw[3] = 0x40;
_.raw[5] = 0xFF;
_.raw[7] = 0xCC;
_.raw[9] = 0x92;
_.raw[11] = 0x43;
// 13-14 is Temperature and parity
_.raw[15] = 0x00;
_.raw[17] = 0x00; // Off timer LSB
_.raw[19] = 0x00; // Off timer cont
_.raw[21] = 0x00; // On timer LSB
_.raw[23] = 0x00; // On timer cont
// 25-26 is Mode and fan
_.raw[27] = 0xF1; // Power on
_.raw[29] = 0x00;
_.raw[31] = 0x00;
_.raw[33] = 0x00;
_.raw[35] = 0x03; // Humidity
setTemp(24);
setMode(kHitachiAc296Heat);
setFan(kHitachiAc296FanAuto);
setInvertedStates();
}
/// Update the internal consistency check for the protocol.
void IRHitachiAc296::setInvertedStates(void) {
invertBytePairs(_.raw + 3, kHitachiAc296StateLength - 3);
}
/// Check if every second byte of the state, after the fixed header
/// is inverted to the previous byte.
/// @param[in] state The state array to be checked.
/// @param[in] length The size of the state array.
/// @note This is this protocols integrity check.
bool IRHitachiAc296::hasInvertedStates(const uint8_t state[],
const uint16_t length) {
return IRHitachiAc3::hasInvertedStates(state, length);
}
/// Set up hardware to be able to send a message.
void IRHitachiAc296::begin(void) { _irsend.begin(); }
#if SEND_HITACHI_AC296
/// Send the current internal state as an IR message.
/// @param[in] repeat Nr. of times the message will be repeated.
void IRHitachiAc296::send(const uint16_t repeat) {
_irsend.sendHitachiAc296(getRaw(), kHitachiAc296StateLength, repeat);
}
#endif // SEND_HITACHI_AC296
/// Get the value of the current power setting.
/// @return true, the setting is on. false, the setting is off.
bool IRHitachiAc296::getPower(void) const { return _.Power; }
/// Change the power setting.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRHitachiAc296::setPower(const bool on) { _.Power = on; }
/// Change the power setting to On.
void IRHitachiAc296::on(void) { setPower(true); }
/// Change the power setting to Off.
void IRHitachiAc296::off(void) { setPower(false); }
/// Get the operating mode setting of the A/C.
/// @return The current operating mode setting.
uint8_t IRHitachiAc296::getMode(void) const { return _.Mode; }
/// Set the operating mode of the A/C.
/// @param[in] mode The desired operating mode.
void IRHitachiAc296::setMode(const uint8_t mode) {
switch (mode) {
case kHitachiAc296Heat:
case kHitachiAc296Cool:
case kHitachiAc296Dehumidify:
case kHitachiAc296AutoDehumidifying:
case kHitachiAc296Auto:
_.Mode = mode;
setTemp(getTemp()); // Reset the temp to handle "Auto"'s special temp.
break;
default:
setMode(kHitachiAc296Auto);
}
}
/// Convert a stdAc::opmode_t enum into its native mode.
/// @param[in] mode The enum to be converted.
/// @return The native equivalent of the enum.
uint8_t IRHitachiAc296::convertMode(const stdAc::opmode_t mode) {
switch (mode) {
case stdAc::opmode_t::kCool: return kHitachiAc296Cool;
case stdAc::opmode_t::kHeat: return kHitachiAc296Heat;
case stdAc::opmode_t::kDry: return kHitachiAc296Dehumidify;
default: return kHitachiAc296Auto;
}
}
/// Convert a native mode into its stdAc equivalent.
/// @param[in] mode The native setting to be converted.
/// @return The stdAc equivalent of the native setting.
stdAc::opmode_t IRHitachiAc296::toCommonMode(const uint8_t mode) {
switch (mode) {
case kHitachiAc296DryCool:
case kHitachiAc296Cool: return stdAc::opmode_t::kCool;
case kHitachiAc296Heat: return stdAc::opmode_t::kHeat;
case kHitachiAc296AutoDehumidifying:
case kHitachiAc296Dehumidify: return stdAc::opmode_t::kDry;
default: return stdAc::opmode_t::kAuto;
}
}
/// Get the current temperature setting.
/// @return The current setting for temp. in degrees celsius.
uint8_t IRHitachiAc296::getTemp(void) const { return _.Temp; }
/// Set the temperature.
/// @param[in] celsius The temperature in degrees celsius.
void IRHitachiAc296::setTemp(const uint8_t celsius) {
uint8_t temp = celsius;
if (getMode() == kHitachiAc296Auto) { // Special temp for auto mode
temp = kHitachiAc296TempAuto;
} else { // Normal temp setting.
temp = std::min(temp, kHitachiAc296MaxTemp);
temp = std::max(temp, kHitachiAc296MinTemp);
}
_.Temp = temp;
}
/// Get the current fan speed setting.
/// @return The current fan speed.
uint8_t IRHitachiAc296::getFan(void) const { return _.Fan; }
/// Set the speed of the fan.
/// @param[in] speed The desired setting.
void IRHitachiAc296::setFan(const uint8_t speed) {
uint8_t newSpeed = std::max(speed, kHitachiAc296FanSilent);
_.Fan = std::min(newSpeed, kHitachiAc296FanAuto);
}
/// Convert a stdAc::fanspeed_t enum into it's native speed.
/// @param[in] speed The enum to be converted.
/// @return The native equivalent of the enum.
uint8_t IRHitachiAc296::convertFan(const stdAc::fanspeed_t speed) {
switch (speed) {
case stdAc::fanspeed_t::kMin: return kHitachiAc296FanSilent;
case stdAc::fanspeed_t::kLow: return kHitachiAc296FanLow;
case stdAc::fanspeed_t::kMedium: return kHitachiAc296FanMedium;
case stdAc::fanspeed_t::kHigh:
case stdAc::fanspeed_t::kMax: return kHitachiAc296FanHigh;
default: return kHitachiAc296FanAuto;
}
}
/// Convert a native fan speed into its stdAc equivalent.
/// @param[in] speed The native setting to be converted.
/// @return The stdAc equivalent of the native setting.
stdAc::fanspeed_t IRHitachiAc296::toCommonFanSpeed(const uint8_t speed) {
switch (speed) {
case kHitachiAc296FanHigh: return stdAc::fanspeed_t::kHigh;
case kHitachiAc296FanMedium: return stdAc::fanspeed_t::kMedium;
case kHitachiAc296FanLow: return stdAc::fanspeed_t::kLow;
case kHitachiAc296FanSilent: return stdAc::fanspeed_t::kMin;
default: return stdAc::fanspeed_t::kAuto;
}
}
/// Get a PTR to the internal state/code for this protocol.
/// @return PTR to a code for this protocol based on the current internal state.
uint8_t *IRHitachiAc296::getRaw(void) {
setInvertedStates();
return _.raw;
}
/// Set the internal state from a valid code for this protocol.
/// @param[in] new_code A valid code for this protocol.
/// @param[in] length Size (in bytes) of the code for this protocol.
void IRHitachiAc296::setRaw(const uint8_t new_code[], const uint16_t length) {
memcpy(_.raw, new_code, std::min(length, kHitachiAc296StateLength));
}
/// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings.
stdAc::state_t IRHitachiAc296::toCommon(void) const {
stdAc::state_t result{};
result.protocol = decode_type_t::HITACHI_AC296;
result.model = -1; // No models used.
result.power = getPower();
result.mode = toCommonMode(_.Mode);
result.celsius = true;
result.degrees = _.Temp;
result.fanspeed = toCommonFanSpeed(_.Fan);
result.quiet = _.Fan == kHitachiAc296FanSilent;
// Not supported.
result.swingv = stdAc::swingv_t::kOff;
result.swingh = stdAc::swingh_t::kOff;
result.turbo = false;
result.clean = false;
result.econo = false;
result.filter = false;
result.light = false;
result.beep = false;
result.sleep = -1;
result.clock = -1;
return result;
}
/// Convert the current internal state into a human readable string.
/// @return A human readable string.
String IRHitachiAc296::toString(void) const {
String result = "";
result.reserve(70); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(_.Power, kPowerStr, false);
result += addModeToString(_.Mode, kHitachiAc296Auto, kHitachiAc296Cool,
kHitachiAc296Heat, kHitachiAc1Dry,
kHitachiAc296Auto);
result += addTempToString(getTemp());
result += addFanToString(_.Fan, kHitachiAc296FanHigh, kHitachiAc296FanLow,
kHitachiAc296FanAuto, kHitachiAc296FanSilent,
kHitachiAc296FanMedium);
return result;
}
#if DECODE_HITACHI_AC296
/// Decode the supplied Hitachi 37-byte A/C message.
/// Status: STABLE / Working on a real device.
/// @param[in,out] results Ptr to the data to decode & where to store the result
/// @param[in] offset The starting index to use when attempting to decode the
/// raw data. Typically/Defaults to kStartOffset.
/// @param[in] nbits The number of data bits to expect.
/// @param[in] strict Flag indicating if we should perform strict matching.
/// @return True if it can decode it, false if it can't.
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1757
bool IRrecv::decodeHitachiAc296(decode_results *results, uint16_t offset,
const uint16_t nbits,
const bool strict) {
if (!matchGeneric(results->rawbuf + offset, results->state,
results->rawlen - offset, nbits,
kHitachiAcHdrMark, kHitachiAcHdrSpace,
kHitachiAcBitMark, kHitachiAcOneSpace,
kHitachiAcBitMark, kHitachiAcZeroSpace,
kHitachiAcBitMark, kHitachiAcMinGap, true,
kUseDefTol, 0, false)) return false;
// Compliance
if (strict && !IRHitachiAc296::hasInvertedStates(results->state, nbits / 8))
return false;
// Success
results->decode_type = decode_type_t::HITACHI_AC296;
results->bits = nbits;
return true;
}
#endif // DECODE_HITACHI_AC296

View File

@ -7,6 +7,8 @@
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1056
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1060
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1134
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1729
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1757
// Supports: // Supports:
// Brand: Hitachi, Model: RAS-35THA6 remote // Brand: Hitachi, Model: RAS-35THA6 remote
@ -19,6 +21,10 @@
// Brand: Hitachi, Model: R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1) // Brand: Hitachi, Model: R-LT0541-HTA/Y.K.1.1-1 V2.3 remote (HITACHI_AC1)
// Brand: Hitachi, Model: RAS-22NK A/C (HITACHI_AC344) // Brand: Hitachi, Model: RAS-22NK A/C (HITACHI_AC344)
// Brand: Hitachi, Model: RF11T1 remote (HITACHI_AC344) // Brand: Hitachi, Model: RF11T1 remote (HITACHI_AC344)
// Brand: Hitachi, Model: RAR-2P2 remote (HITACHI_AC264)
// Brand: Hitachi, Model: RAK-25NH5 A/C (HITACHI_AC264)
// Brand: Hitachi, Model: RAR-3U3 remote (HITACHI_AC296)
// Brand: Hitachi, Model: RAS-70YHA3 A/C (HITACHI_AC296)
#ifndef IR_HITACHI_H_ #ifndef IR_HITACHI_H_
#define IR_HITACHI_H_ #define IR_HITACHI_H_
@ -102,7 +108,9 @@ union Hitachi424Protocol{
// Byte 26 // Byte 26
uint8_t :8; uint8_t :8;
// Byte 27 // Byte 27
uint8_t Power :8; uint8_t :4;
uint8_t Power :1;
uint8_t :3;
// Byte 28~34 // Byte 28~34
uint8_t pad2[7]; uint8_t pad2[7];
// Byte 35 // Byte 35
@ -160,9 +168,6 @@ const uint8_t kHitachiAc344FanHigh = kHitachiAc424FanHigh;
const uint8_t kHitachiAc344FanAuto = kHitachiAc424FanAuto; const uint8_t kHitachiAc344FanAuto = kHitachiAc424FanAuto;
const uint8_t kHitachiAc344FanMax = kHitachiAc424FanMax; const uint8_t kHitachiAc344FanMax = kHitachiAc424FanMax;
const uint8_t kHitachiAc424PowerOn = 0xF1;
const uint8_t kHitachiAc424PowerOff = 0xE1;
const uint8_t kHitachiAc344SwingHAuto = 0; // 0b000 const uint8_t kHitachiAc344SwingHAuto = 0; // 0b000
const uint8_t kHitachiAc344SwingHRightMax = 1; // 0b001 const uint8_t kHitachiAc344SwingHRightMax = 1; // 0b001
const uint8_t kHitachiAc344SwingHRight = 2; // 0b010 const uint8_t kHitachiAc344SwingHRight = 2; // 0b010
@ -240,6 +245,127 @@ const uint8_t kHitachiAc1Sleep4 = 0b100;
const uint8_t kHitachiAc1ChecksumStartByte = 5; const uint8_t kHitachiAc1ChecksumStartByte = 5;
/// Native representation of a Hitachi 164-bit A/C message.
union HitachiAC264Protocol{
uint8_t raw[kHitachiAc264StateLength]; ///< The state in native code.
struct {
// Bytes 0~10
uint8_t pad0[11];
// Byte 11
uint8_t Button :8;
// Byte 12
uint8_t :8;
// Byte 13
uint8_t :2;
uint8_t Temp :6;
// Byte 14
uint8_t :8;
// Bytes 14~24
uint8_t pad1[10];
// Byte 25
uint8_t Mode :4;
uint8_t Fan :4;
// Byte 26
uint8_t :8;
// Byte 27
uint8_t :4;
uint8_t Power :1;
uint8_t :3;
// Byte 28
uint8_t :8;
// Bytes 29~32
uint8_t pad2[4];
};
};
// HitachiAc264
const uint8_t kHitachiAc264ButtonPowerMode = kHitachiAc424ButtonPowerMode;
const uint8_t kHitachiAc264ButtonFan = kHitachiAc424ButtonFan;
const uint8_t kHitachiAc264ButtonTempDown = kHitachiAc424ButtonTempDown;
const uint8_t kHitachiAc264ButtonTempUp = kHitachiAc424ButtonTempUp;
const uint8_t kHitachiAc264ButtonSwingV = kHitachiAc424ButtonSwingV;
const uint8_t kHitachiAc264MinTemp = kHitachiAc424MinTemp; // 16C
const uint8_t kHitachiAc264MaxTemp = kHitachiAc424MaxTemp; // 32C
const uint8_t kHitachiAc264Fan = kHitachiAc424Fan;
const uint8_t kHitachiAc264Cool = kHitachiAc424Cool;
const uint8_t kHitachiAc264Dry = kHitachiAc424Dry;
const uint8_t kHitachiAc264Heat = kHitachiAc424Heat;
const uint8_t kHitachiAc264FanMin = kHitachiAc424FanMin;
const uint8_t kHitachiAc264FanLow = kHitachiAc424FanMin;
const uint8_t kHitachiAc264FanMedium = kHitachiAc424FanMedium;
const uint8_t kHitachiAc264FanHigh = kHitachiAc424FanHigh;
const uint8_t kHitachiAc264FanAuto = kHitachiAc424FanAuto;
// HitachiAc296
union HitachiAC296Protocol{
uint8_t raw[kHitachiAc296StateLength];
struct {
// Byte 0~12
uint8_t pad0[13];
// Byte 13
uint8_t :2;
uint8_t Temp :5; // LSB
uint8_t :1;
uint8_t :8;
// Byte 15~16
uint8_t :8;
uint8_t :8;
// Byte 17~24
uint8_t OffTimerLow :8; // LSB
uint8_t /* Parity */ :8;
uint8_t OffTimerHigh :8;
uint8_t /* Parity */ :8;
uint8_t OnTimerLow :8; // LSB
uint8_t /* Parity */ :8;
uint8_t OnTimerHigh :4;
uint8_t OffTimerActive :1;
uint8_t OnTimerActive :1;
uint8_t :2;
uint8_t /* Parity */ :8;
// Byte 25~26
uint8_t Mode :4;
uint8_t Fan :3;
uint8_t :1;
uint8_t :8;
// Byte 27~28
uint8_t :4;
uint8_t Power :1;
uint8_t :2;
uint8_t TimerActive :1;
uint8_t :8;
// Byte 29~34
uint8_t pad1[6];
// Byte 35~36
uint8_t :4;
uint8_t Humidity :4; // LSB
uint8_t :8;
};
};
// Mode & Fan
const uint8_t kHitachiAc296Cool = 0b0011;
const uint8_t kHitachiAc296DryCool = 0b0100;
const uint8_t kHitachiAc296Dehumidify = 0b0101;
const uint8_t kHitachiAc296Heat = 0b0110;
const uint8_t kHitachiAc296Auto = 0b0111;
const uint8_t kHitachiAc296AutoDehumidifying = 0b1001;
const uint8_t kHitachiAc296QuickLaundry = 0b1010;
const uint8_t kHitachiAc296CondensationControl = 0b1100;
const uint8_t kHitachiAc296FanSilent = 0b001;
const uint8_t kHitachiAc296FanLow = 0b010;
const uint8_t kHitachiAc296FanMedium = 0b011;
const uint8_t kHitachiAc296FanHigh = 0b100;
const uint8_t kHitachiAc296FanAuto = 0b101;
const uint8_t kHitachiAc296TempAuto = 1; // Special value for "Auto" op mode.
const uint8_t kHitachiAc296MinTemp = 16;
const uint8_t kHitachiAc296MaxTemp = 31; // Max value you can store in 5 bits.
const uint8_t kHitachiAc296PowerOn = 1;
const uint8_t kHitachiAc296PowerOff = 0;
// Classes // Classes
/// Class for handling detailed Hitachi 224-bit A/C messages. /// Class for handling detailed Hitachi 224-bit A/C messages.
/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/HitachiHeatpumpIR.cpp /// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/HitachiHeatpumpIR.cpp
@ -369,6 +495,7 @@ class IRHitachiAc1 {
/// Class for handling detailed Hitachi 53-byte/424-bit A/C messages. /// Class for handling detailed Hitachi 53-byte/424-bit A/C messages.
class IRHitachiAc424 { class IRHitachiAc424 {
friend class IRHitachiAc264;
friend class IRHitachiAc344; friend class IRHitachiAc344;
public: public:
explicit IRHitachiAc424(const uint16_t pin, const bool inverted = false, explicit IRHitachiAc424(const uint16_t pin, const bool inverted = false,
@ -389,7 +516,7 @@ class IRHitachiAc424 {
bool getPower(void) const; bool getPower(void) const;
void setTemp(const uint8_t temp, bool setPrevious = true); void setTemp(const uint8_t temp, bool setPrevious = true);
uint8_t getTemp(void) const; uint8_t getTemp(void) const;
void setFan(const uint8_t speed); virtual void setFan(const uint8_t speed);
uint8_t getFan(void) const; uint8_t getFan(void) const;
uint8_t getButton(void) const; uint8_t getButton(void) const;
void setButton(const uint8_t button); void setButton(const uint8_t button);
@ -401,9 +528,9 @@ class IRHitachiAc424 {
virtual void setRaw(const uint8_t new_code[], virtual void setRaw(const uint8_t new_code[],
const uint16_t length = kHitachiAc424StateLength); const uint16_t length = kHitachiAc424StateLength);
static uint8_t convertMode(const stdAc::opmode_t mode); static uint8_t convertMode(const stdAc::opmode_t mode);
static uint8_t convertFan(const stdAc::fanspeed_t speed); virtual uint8_t convertFan(const stdAc::fanspeed_t speed) const;
static stdAc::opmode_t toCommonMode(const uint8_t mode); static stdAc::opmode_t toCommonMode(const uint8_t mode);
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); virtual stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed) const;
virtual stdAc::state_t toCommon(void) const; virtual stdAc::state_t toCommon(void) const;
virtual String toString(void) const; virtual String toString(void) const;
#ifndef UNIT_TEST #ifndef UNIT_TEST
@ -475,4 +602,66 @@ class IRHitachiAc344: public IRHitachiAc424 {
static stdAc::swingh_t toCommonSwingH(const uint8_t pos); static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
String toString(void) const override; String toString(void) const override;
}; };
/// Class for handling detailed Hitachi 264-bit A/C messages.
class IRHitachiAc264: public IRHitachiAc424 {
public:
explicit IRHitachiAc264(const uint16_t pin, const bool inverted = false,
const bool use_modulation = true);
void stateReset(void) override;
void setRaw(const uint8_t new_code[],
const uint16_t length = kHitachiAc264StateLength) override;
void setFan(const uint8_t speed) override;
uint8_t convertFan(const stdAc::fanspeed_t speed) const override;
stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed) const override;
stdAc::state_t toCommon(void) const override;
#if SEND_HITACHI_AC264
void send(const uint16_t repeat = kHitachiAcDefaultRepeat) override;
#endif // SEND_HITACHI_AC264
String toString(void) const override;
};
class IRHitachiAc296 {
public:
explicit IRHitachiAc296(const uint16_t pin, const bool inverted = false,
const bool use_modulation = true);
void stateReset(void);
#if SEND_HITACHI_AC296
void send(const uint16_t repeat = kHitachiAcDefaultRepeat);
#endif // SEND_HITACHI_AC296
void begin(void);
void on(void);
void off(void);
void setPower(const bool on);
bool getPower(void) const;
void setTemp(const uint8_t temp);
uint8_t getTemp(void) const;
void setFan(const uint8_t speed);
uint8_t getFan(void) const;
void setMode(const uint8_t mode);
uint8_t getMode(void) const;
static bool hasInvertedStates(const uint8_t state[], const uint16_t length);
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[],
const uint16_t length = kHitachiAc296StateLength);
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(void) const;
String toString(void) const;
#ifndef UNIT_TEST
private:
IRsend _irsend; ///< Instance of the IR send class
#else // UNIT_TEST
/// @cond IGNORE
IRsendTest _irsend; ///< Instance of the testing IR send class
/// @endcond
#endif // UNIT_TEST
HitachiAC296Protocol _;
void setInvertedStates(void);
};
#endif // IR_HITACHI_H_ #endif // IR_HITACHI_H_

View File

@ -1,7 +1,8 @@
// Copyright 2021 Davide Depau // Copyright 2021 Davide Depau
// Copyright 2022 David Conran
/// @file /// @file
/// @brief Support for Kelan AC protocol. /// @brief Support for Kelon AC protocols.
/// Both sending and decoding should be functional for models of series /// Both sending and decoding should be functional for models of series
/// KELON ON/OFF 9000-12000. /// KELON ON/OFF 9000-12000.
/// All features of the standard remote are implemented. /// All features of the standard remote are implemented.
@ -12,6 +13,7 @@
/// - Fahrenheit. /// - Fahrenheit.
#include <algorithm> #include <algorithm>
#include <cassert>
#include "ir_Kelon.h" #include "ir_Kelon.h"
@ -39,9 +41,13 @@ const uint16_t kKelonZeroSpace = 600;
const uint32_t kKelonGap = 2 * kDefaultMessageGap; const uint32_t kKelonGap = 2 * kDefaultMessageGap;
const uint16_t kKelonFreq = 38000; const uint16_t kKelonFreq = 38000;
#if SEND_KELON const uint32_t kKelon168FooterSpace = 8000;
const uint16_t kKelon168Section1Size = 6;
const uint16_t kKelon168Section2Size = 8;
const uint16_t kKelon168Section3Size = 7;
/// Send a Kelon message. #if SEND_KELON
/// Send a Kelon 48-bit message.
/// Status: STABLE / Working. /// Status: STABLE / Working.
/// @param[in] data The data to be transmitted. /// @param[in] data The data to be transmitted.
/// @param[in] nbits Nr. of bits of data to be sent. /// @param[in] nbits Nr. of bits of data to be sent.
@ -53,13 +59,12 @@ void IRsend::sendKelon(const uint64_t data, const uint16_t nbits,
kKelonBitMark, kKelonZeroSpace, kKelonBitMark, kKelonZeroSpace,
kKelonBitMark, kKelonGap, kKelonBitMark, kKelonGap,
data, nbits, kKelonFreq, false, // LSB First. data, nbits, kKelonFreq, false, // LSB First.
repeat, 50); repeat, kDutyDefault);
} }
#endif // SEND_KELON #endif // SEND_KELON
#if DECODE_KELON #if DECODE_KELON
/// Decode the supplied Kelon message. /// Decode the supplied Kelon 48-bit message.
/// Status: STABLE / Working. /// Status: STABLE / Working.
/// @param[in,out] results Ptr to the data to decode & where to store the result /// @param[in,out] results Ptr to the data to decode & where to store the result
/// @param[in] offset The starting index to use when attempting to decode the /// @param[in] offset The starting index to use when attempting to decode the
@ -67,27 +72,24 @@ void IRsend::sendKelon(const uint64_t data, const uint16_t nbits,
/// @param[in] nbits The number of data bits to expect. /// @param[in] nbits The number of data bits to expect.
/// @param[in] strict Flag indicating if we should perform strict matching. /// @param[in] strict Flag indicating if we should perform strict matching.
/// @return True if it can decode it, false if it can't. /// @return True if it can decode it, false if it can't.
bool IRrecv::decodeKelon(decode_results *results, uint16_t offset, bool IRrecv::decodeKelon(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) { const uint16_t nbits, const bool strict) {
if (strict && nbits != kKelonBits) { if (strict && nbits != kKelonBits) return false;
return false;
} if (!matchGeneric(results->rawbuf + offset, &(results->value),
if (!matchGeneric(results->rawbuf + offset, results->state,
results->rawlen - offset, nbits, results->rawlen - offset, nbits,
kKelonHdrMark, kKelonHdrSpace, kKelonHdrMark, kKelonHdrSpace,
kKelonBitMark, kKelonOneSpace, kKelonBitMark, kKelonOneSpace,
kKelonBitMark, kKelonZeroSpace, kKelonBitMark, kKelonZeroSpace,
kKelonBitMark, 0, false, kKelonBitMark, kKelonGap, true,
_tolerance, 0, false)) { _tolerance, 0, false)) return false;
return false;
}
results->decode_type = decode_type_t::KELON; results->decode_type = decode_type_t::KELON;
results->address = 0;
results->command = 0;
results->bits = nbits; results->bits = nbits;
return true; return true;
} }
#endif // DECODE_KELON #endif // DECODE_KELON
/// Class constructor /// Class constructor
@ -151,21 +153,15 @@ void IRKelonAc::ensurePower(bool on) {
#endif // SEND_KELON #endif // SEND_KELON
/// Set up hardware to be able to send a message. /// Set up hardware to be able to send a message.
void IRKelonAc::begin() { void IRKelonAc::begin() { _irsend.begin(); }
_irsend.begin();
}
/// Request toggling power - will be reset to false after sending /// Request toggling power - will be reset to false after sending
/// @param[in] toggle Whether to toggle the power state /// @param[in] toggle Whether to toggle the power state
void IRKelonAc::setTogglePower(const bool toggle) { void IRKelonAc::setTogglePower(const bool toggle) { _.PowerToggle = toggle; }
_.PowerToggle = toggle;
}
/// Get whether toggling power will be requested /// Get whether toggling power will be requested
/// @return The power toggle state /// @return The power toggle state
bool IRKelonAc::getTogglePower() const { bool IRKelonAc::getTogglePower() const { return _.PowerToggle; }
return _.PowerToggle;
}
/// Set the temperature setting. /// Set the temperature setting.
/// @param[in] degrees The temperature in degrees celsius. /// @param[in] degrees The temperature in degrees celsius.
@ -178,9 +174,7 @@ void IRKelonAc::setTemp(const uint8_t degrees) {
/// Get the current temperature setting. /// Get the current temperature setting.
/// @return Get current setting for temp. in degrees celsius. /// @return Get current setting for temp. in degrees celsius.
uint8_t IRKelonAc::getTemp() const { uint8_t IRKelonAc::getTemp() const { return _.Temperature + kKelonMinTemp; }
return _.Temperature + kKelonMinTemp;
}
/// Set the speed of the fan. /// Set the speed of the fan.
/// @param[in] speed 0 is auto, 1-5 is the speed /// @param[in] speed 0 is auto, 1-5 is the speed
@ -207,11 +201,10 @@ void IRKelonAc::setDryGrade(const int8_t grade) {
// Two's complement is clearly too bleeding edge for this manufacturer // Two's complement is clearly too bleeding edge for this manufacturer
uint8_t outval; uint8_t outval;
if (drygrade < 0) { if (drygrade < 0)
outval = 0b100 | (-drygrade & 0b011); outval = 0b100 | (-drygrade & 0b011);
} else { else
outval = drygrade & 0b011; outval = drygrade & 0b011;
}
_.DehumidifierGrade = outval; _.DehumidifierGrade = outval;
} }
@ -260,9 +253,7 @@ void IRKelonAc::setMode(const uint8_t mode) {
/// Get the current operation mode setting. /// Get the current operation mode setting.
/// @return The current operation mode. /// @return The current operation mode.
uint8_t IRKelonAc::getMode() const { uint8_t IRKelonAc::getMode() const { return _.Mode; }
return _.Mode;
}
/// Request toggling the vertical swing - will be reset to false after sending /// Request toggling the vertical swing - will be reset to false after sending
/// @param[in] toggle If true, the swing mode will be toggled when sent. /// @param[in] toggle If true, the swing mode will be toggled when sent.
@ -272,21 +263,15 @@ void IRKelonAc::setToggleSwingVertical(const bool toggle) {
/// Get whether the swing mode is set to be toggled /// Get whether the swing mode is set to be toggled
/// @return Whether the toggle bit is set /// @return Whether the toggle bit is set
bool IRKelonAc::getToggleSwingVertical() const { bool IRKelonAc::getToggleSwingVertical() const { return _.SwingVToggle; }
return _.SwingVToggle;
}
/// Control the current sleep (quiet) setting. /// Control the current sleep (quiet) setting.
/// @param[in] on The desired setting. /// @param[in] on The desired setting.
void IRKelonAc::setSleep(const bool on) { void IRKelonAc::setSleep(const bool on) { _.SleepEnabled = on; }
_.SleepEnabled = on;
}
/// Is the sleep setting on? /// Is the sleep setting on?
/// @return The current value. /// @return The current value.
bool IRKelonAc::getSleep() const { bool IRKelonAc::getSleep() const { return _.SleepEnabled; }
return _.SleepEnabled;
}
/// Control the current super cool mode setting. /// Control the current super cool mode setting.
/// @param[in] on The desired setting. /// @param[in] on The desired setting.
@ -305,9 +290,7 @@ void IRKelonAc::setSupercool(const bool on) {
/// Is the super cool mode setting on? /// Is the super cool mode setting on?
/// @return The current value. /// @return The current value.
bool IRKelonAc::getSupercool() const { bool IRKelonAc::getSupercool() const { return _.SuperCoolEnabled1; }
return _.SuperCoolEnabled1;
}
/// Set the timer time and enable it. Timer is an off timer if the unit is on, /// Set the timer time and enable it. Timer is an off timer if the unit is on,
/// it is an on timer if the unit is off. /// it is an on timer if the unit is off.
@ -334,54 +317,39 @@ void IRKelonAc::setTimer(uint16_t mins) {
/// later disabled. /// later disabled.
/// @return The timer set minutes /// @return The timer set minutes
uint16_t IRKelonAc::getTimer() const { uint16_t IRKelonAc::getTimer() const {
if (_.TimerHours >= 10) { if (_.TimerHours >= 10)
return ((uint16_t) ((_.TimerHours << 1) | _.TimerHalfHour) - 10) * 60; return ((uint16_t) ((_.TimerHours << 1) | _.TimerHalfHour) - 10) * 60;
}
return (((uint16_t) _.TimerHours) * 60) + (_.TimerHalfHour ? 30 : 0); return (((uint16_t) _.TimerHours) * 60) + (_.TimerHalfHour ? 30 : 0);
} }
/// Enable or disable the timer. Note that in order to enable the timer the /// Enable or disable the timer. Note that in order to enable the timer the
/// minutes must be set with setTimer(). /// minutes must be set with setTimer().
/// @param[in] on Whether to enable or disable the timer /// @param[in] on Whether to enable or disable the timer
void IRKelonAc::setTimerEnabled(bool on) { void IRKelonAc::setTimerEnabled(bool on) { _.TimerEnabled = on; }
_.TimerEnabled = on;
}
/// Get the current timer status /// Get the current timer status
/// @return Whether the timer is enabled. /// @return Whether the timer is enabled.
bool IRKelonAc::getTimerEnabled() const { bool IRKelonAc::getTimerEnabled() const { return _.TimerEnabled; }
return _.TimerEnabled;
}
/// Get the raw state of the object, suitable to be sent with the appropriate /// Get the raw state of the object, suitable to be sent with the appropriate
/// IRsend object method. /// IRsend object method.
/// @return A PTR to the internal state. /// @return A PTR to the internal state.
uint64_t IRKelonAc::getRaw() const { uint64_t IRKelonAc::getRaw() const { return _.raw; }
return _.raw;
}
/// Set the raw state of the object. /// Set the raw state of the object.
/// @param[in] new_code The raw state from the native IR message. /// @param[in] new_code The raw state from the native IR message.
void IRKelonAc::setRaw(const uint64_t new_code) { void IRKelonAc::setRaw(const uint64_t new_code) { _.raw = new_code; }
_.raw = new_code;
}
/// Convert a standard A/C mode (stdAc::opmode_t) into it a native mode. /// Convert a standard A/C mode (stdAc::opmode_t) into it a native mode.
/// @param[in] mode A stdAc::opmode_t operation mode. /// @param[in] mode A stdAc::opmode_t operation mode.
/// @return The native mode equivalent. /// @return The native mode equivalent.
uint8_t IRKelonAc::convertMode(const stdAc::opmode_t mode) { uint8_t IRKelonAc::convertMode(const stdAc::opmode_t mode) {
switch (mode) { switch (mode) {
case stdAc::opmode_t::kCool: case stdAc::opmode_t::kCool: return kKelonModeCool;
return kKelonModeCool; case stdAc::opmode_t::kHeat: return kKelonModeHeat;
case stdAc::opmode_t::kHeat: case stdAc::opmode_t::kDry: return kKelonModeDry;
return kKelonModeHeat; case stdAc::opmode_t::kFan: return kKelonModeFan;
case stdAc::opmode_t::kDry: default: return kKelonModeSmart; // aka Auto.
return kKelonModeDry;
case stdAc::opmode_t::kFan:
return kKelonModeFan;
default:
return kKelonModeSmart;
} }
} }
@ -391,15 +359,11 @@ uint8_t IRKelonAc::convertMode(const stdAc::opmode_t mode) {
uint8_t IRKelonAc::convertFan(stdAc::fanspeed_t fan) { uint8_t IRKelonAc::convertFan(stdAc::fanspeed_t fan) {
switch (fan) { switch (fan) {
case stdAc::fanspeed_t::kMin: case stdAc::fanspeed_t::kMin:
case stdAc::fanspeed_t::kLow: case stdAc::fanspeed_t::kLow: return kKelonFanMin;
return kKelonFanMin; case stdAc::fanspeed_t::kMedium: return kKelonFanMedium;
case stdAc::fanspeed_t::kMedium:
return kKelonFanMedium;
case stdAc::fanspeed_t::kHigh: case stdAc::fanspeed_t::kHigh:
case stdAc::fanspeed_t::kMax: case stdAc::fanspeed_t::kMax: return kKelonFanMax;
return kKelonFanMax; default: return kKelonFanAuto;
default:
return kKelonFanAuto;
} }
} }
@ -408,16 +372,11 @@ uint8_t IRKelonAc::convertFan(stdAc::fanspeed_t fan) {
/// @return The stdAc::opmode_t equivalent. /// @return The stdAc::opmode_t equivalent.
stdAc::opmode_t IRKelonAc::toCommonMode(const uint8_t mode) { stdAc::opmode_t IRKelonAc::toCommonMode(const uint8_t mode) {
switch (mode) { switch (mode) {
case kKelonModeCool: case kKelonModeCool: return stdAc::opmode_t::kCool;
return stdAc::opmode_t::kCool; case kKelonModeHeat: return stdAc::opmode_t::kHeat;
case kKelonModeHeat: case kKelonModeDry: return stdAc::opmode_t::kDry;
return stdAc::opmode_t::kHeat; case kKelonModeFan: return stdAc::opmode_t::kFan;
case kKelonModeDry: default: return stdAc::opmode_t::kAuto;
return stdAc::opmode_t::kDry;
case kKelonModeFan:
return stdAc::opmode_t::kFan;
default:
return stdAc::opmode_t::kAuto;
} }
} }
@ -426,14 +385,10 @@ stdAc::opmode_t IRKelonAc::toCommonMode(const uint8_t mode) {
/// @return The stdAc::fanspeed_t equivalent. /// @return The stdAc::fanspeed_t equivalent.
stdAc::fanspeed_t IRKelonAc::toCommonFanSpeed(const uint8_t speed) { stdAc::fanspeed_t IRKelonAc::toCommonFanSpeed(const uint8_t speed) {
switch (speed) { switch (speed) {
case kKelonFanMin: case kKelonFanMin: return stdAc::fanspeed_t::kLow;
return stdAc::fanspeed_t::kLow; case kKelonFanMedium: return stdAc::fanspeed_t::kMedium;
case kKelonFanMedium: case kKelonFanMax: return stdAc::fanspeed_t::kHigh;
return stdAc::fanspeed_t::kMedium; default: return stdAc::fanspeed_t::kAuto;
case kKelonFanMax:
return stdAc::fanspeed_t::kHigh;
default:
return stdAc::fanspeed_t::kAuto;
} }
} }
@ -443,21 +398,20 @@ stdAc::state_t IRKelonAc::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result{}; stdAc::state_t result{};
result.protocol = decode_type_t::KELON; result.protocol = decode_type_t::KELON;
result.model = -1; // Unused. result.model = -1; // Unused.
// AC only supports toggling it
result.power = (prev == nullptr || prev->power) ^ _.PowerToggle;
result.mode = toCommonMode(getMode()); result.mode = toCommonMode(getMode());
result.celsius = true; result.celsius = true;
result.degrees = getTemp(); result.degrees = getTemp();
result.fanspeed = toCommonFanSpeed(getFan()); result.fanspeed = toCommonFanSpeed(getFan());
// AC only supports toggling it
result.swingv = stdAc::swingv_t::kAuto;
if (prev != nullptr &&
(prev->swingv != stdAc::swingv_t::kAuto) ^ _.SwingVToggle)
result.swingv = stdAc::swingv_t::kOff;
result.turbo = getSupercool(); result.turbo = getSupercool();
result.sleep = getSleep() ? 0 : -1; result.sleep = getSleep() ? 0 : -1;
// Not supported. // Not supported.
// N/A, AC only supports toggling it
result.power = (prev == nullptr || prev->power) ^ _.PowerToggle;
// N/A, AC only supports toggling it
result.swingv = stdAc::swingv_t::kAuto;
if (prev != nullptr &&
(prev->swingv != stdAc::swingv_t::kAuto) ^ _.SwingVToggle) {
result.swingv = stdAc::swingv_t::kOff;
}
result.swingh = stdAc::swingh_t::kOff; result.swingh = stdAc::swingh_t::kOff;
result.light = true; result.light = true;
result.beep = true; result.beep = true;
@ -483,20 +437,115 @@ String IRKelonAc::toString() const {
result += addBoolToString(_.SleepEnabled, kSleepStr); result += addBoolToString(_.SleepEnabled, kSleepStr);
result += addSignedIntToString(getDryGrade(), kDryStr); result += addSignedIntToString(getDryGrade(), kDryStr);
result += addLabeledString( result += addLabeledString(
getTimerEnabled() getTimerEnabled() ? (getTimer() > 0 ? minsToString(getTimer()) : kOnStr)
? ( : kOffStr,
getTimer() > 0
? minsToString(getTimer())
: kOnStr
)
: kOffStr,
kTimerStr); kTimerStr);
result += addBoolToString(getSupercool(), kTurboStr); result += addBoolToString(getSupercool(), kTurboStr);
if (getTogglePower()) { if (getTogglePower())
result += addBoolToString(true, kPowerToggleStr); result += addBoolToString(true, kPowerToggleStr);
} if (getToggleSwingVertical())
if (getToggleSwingVertical()) {
result += addBoolToString(true, kSwingVToggleStr); result += addBoolToString(true, kSwingVToggleStr);
}
return result; return result;
} }
#if SEND_KELON168
/// Send a Kelon 168 bit / 21 byte message.
/// Status: BETA / Probably works.
/// @param[in] data The data to be transmitted.
/// @param[in] nbytes Nr. of bytes of data to be sent.
/// @param[in] repeat The number of times the command is to be repeated.
void IRsend::sendKelon168(const uint8_t data[], const uint16_t nbytes,
const uint16_t repeat) {
assert(kKelon168StateLength == kKelon168Section1Size + kKelon168Section2Size +
kKelon168Section3Size);
// Enough bytes to send a proper message?
if (nbytes < kKelon168StateLength) return;
for (uint16_t r = 0; r <= repeat; r++) {
// Section #1 (48 bits)
sendGeneric(kKelonHdrMark, kKelonHdrSpace,
kKelonBitMark, kKelonOneSpace,
kKelonBitMark, kKelonZeroSpace,
kKelonBitMark, kKelon168FooterSpace,
data, kKelon168Section1Size, kKelonFreq, false, // LSB First.
0, // No repeats here
kDutyDefault);
// Section #2 (64 bits)
sendGeneric(0, 0,
kKelonBitMark, kKelonOneSpace,
kKelonBitMark, kKelonZeroSpace,
kKelonBitMark, kKelon168FooterSpace,
data + kKelon168Section1Size, kKelon168Section2Size,
kKelonFreq, false, // LSB First.
0, // No repeats here
kDutyDefault);
// Section #3 (56 bits)
sendGeneric(0, 0,
kKelonBitMark, kKelonOneSpace,
kKelonBitMark, kKelonZeroSpace,
kKelonBitMark, kKelonGap,
data + kKelon168Section1Size + kKelon168Section2Size,
nbytes - (kKelon168Section1Size + kKelon168Section2Size),
kKelonFreq, false, // LSB First.
0, // No repeats here
kDutyDefault);
}
}
#endif // SEND_KELON168
#if DECODE_KELON168
/// Decode the supplied Kelon 168 bit / 21 byte message.
/// Status: BETA / Probably Working.
/// @param[in,out] results Ptr to the data to decode & where to store the result
/// @param[in] offset The starting index to use when attempting to decode the
/// raw data. Typically/Defaults to kStartOffset.
/// @param[in] nbits The number of data bits to expect.
/// @param[in] strict Flag indicating if we should perform strict matching.
/// @return True if it can decode it, false if it can't.
bool IRrecv::decodeKelon168(decode_results *results, uint16_t offset,
const uint16_t nbits, const bool strict) {
if (strict && nbits != kKelon168Bits) return false;
if (results->rawlen <= 2 * nbits + kHeader + kFooter * 2 - 1 + offset)
return false; // Can't possibly be a valid Kelon 168 bit message.
uint16_t used = 0;
used = matchGeneric(results->rawbuf + offset, results->state,
results->rawlen - offset, kKelon168Section1Size * 8,
kKelonHdrMark, kKelonHdrSpace,
kKelonBitMark, kKelonOneSpace,
kKelonBitMark, kKelonZeroSpace,
kKelonBitMark, kKelon168FooterSpace,
false, _tolerance, 0, false);
if (!used) return false; // Failed to match.
offset += used;
used = matchGeneric(results->rawbuf + offset,
results->state + kKelon168Section1Size,
results->rawlen - offset, kKelon168Section2Size * 8,
0, 0,
kKelonBitMark, kKelonOneSpace,
kKelonBitMark, kKelonZeroSpace,
kKelonBitMark, kKelon168FooterSpace,
false, _tolerance, 0, false);
if (!used) return false; // Failed to match.
offset += used;
used = matchGeneric(results->rawbuf + offset,
results->state + (kKelon168Section1Size +
kKelon168Section2Size),
results->rawlen - offset,
nbits - (kKelon168Section1Size +
kKelon168Section2Size) * 8,
0, 0,
kKelonBitMark, kKelonOneSpace,
kKelonBitMark, kKelonZeroSpace,
kKelonBitMark, kKelonGap,
true, _tolerance, 0, false);
if (!used) return false; // Failed to match.
results->decode_type = decode_type_t::KELON168;
results->bits = nbits;
return true;
}
#endif // DECODE_KELON168

View File

@ -2,16 +2,23 @@
/// @file /// @file
/// @brief Support for Kelan AC protocol. /// @brief Support for Kelan AC protocol.
/// Both sending and decoding should be functional for models of series KELON /// @note Both sending and decoding should be functional for models of series
/// ON/OFF 9000-12000. /// KELON ON/OFF 9000-12000.
/// All features of the standard remote are implemented. /// All features of the standard remote are implemented.
/// ///
/// @note Unsupported: /// @note Unsupported:
/// - Explicit on/off due to AC unit limitations /// - Explicit on/off due to AC unit limitations
/// - Explicit swing position due to AC unit limitations /// - Explicit swing position due to AC unit limitations
/// - Fahrenheit. /// - Fahrenheit.
///
/// For KELON168:
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1745
// Supports: // Supports:
// Brand: Kelon, Model: ON/OFF 9000-12000 // Brand: Kelon, Model: ON/OFF 9000-12000 (KELON)
// Brand: Kelon, Model: DG11R2-01 remote (KELON168)
// Brand: Kelon, Model: AST-09UW4RVETG00A A/C (KELON168)
// Brand: Hisense, Model: AST-09UW4RVETG00A A/C (KELON168)
#ifndef IR_KELON_H_ #ifndef IR_KELON_H_
#define IR_KELON_H_ #define IR_KELON_H_
@ -71,84 +78,50 @@ class IRKelonAc {
public: public:
explicit IRKelonAc(uint16_t pin, bool inverted = false, explicit IRKelonAc(uint16_t pin, bool inverted = false,
bool use_modulation = true); bool use_modulation = true);
void stateReset(void); void stateReset(void);
#if SEND_KELON #if SEND_KELON
void send(const uint16_t repeat = kNoRepeat); void send(const uint16_t repeat = kNoRepeat);
/// Run the calibration to calculate uSec timing offsets for this platform. /// Run the calibration to calculate uSec timing offsets for this platform.
/// @return The uSec timing offset needed per modulation of the IR Led. /// @return The uSec timing offset needed per modulation of the IR Led.
/// @note This will produce a 65ms IR signal pulse at 38kHz. /// @note This will produce a 65ms IR signal pulse at 38kHz.
/// Only ever needs to be run once per object instantiation, if at all. /// Only ever needs to be run once per object instantiation, if at all.
int8_t calibrate(void) { return _irsend.calibrate(); } int8_t calibrate(void) { return _irsend.calibrate(); }
/// Since the AC does not support actually setting the power state to a known /// Since the AC does not support actually setting the power state to a known
/// value, this utility allow ensuring the AC is on or off by exploiting /// value, this utility allow ensuring the AC is on or off by exploiting
/// the fact that the AC, according to the user manual, will always turn on /// the fact that the AC, according to the user manual, will always turn on
/// when setting it to "smart" or "super" mode. /// when setting it to "smart" or "super" mode.
void ensurePower(const bool on); void ensurePower(const bool on);
#endif // SEND_KELON
#endif
void begin(void); void begin(void);
void setTogglePower(const bool toggle); void setTogglePower(const bool toggle);
bool getTogglePower(void) const; bool getTogglePower(void) const;
void setTemp(const uint8_t degrees); void setTemp(const uint8_t degrees);
uint8_t getTemp(void) const; uint8_t getTemp(void) const;
void setFan(const uint8_t speed); void setFan(const uint8_t speed);
uint8_t getFan(void) const; uint8_t getFan(void) const;
void setDryGrade(const int8_t grade); void setDryGrade(const int8_t grade);
int8_t getDryGrade(void) const; int8_t getDryGrade(void) const;
void setMode(const uint8_t mode); void setMode(const uint8_t mode);
uint8_t getMode(void) const; uint8_t getMode(void) const;
void setToggleSwingVertical(const bool toggle); void setToggleSwingVertical(const bool toggle);
bool getToggleSwingVertical(void) const; bool getToggleSwingVertical(void) const;
void setSleep(const bool on); void setSleep(const bool on);
bool getSleep(void) const; bool getSleep(void) const;
void setSupercool(const bool on); void setSupercool(const bool on);
bool getSupercool(void) const; bool getSupercool(void) const;
void setTimer(const uint16_t mins); void setTimer(const uint16_t mins);
uint16_t getTimer(void) const; uint16_t getTimer(void) const;
void setTimerEnabled(const bool on); void setTimerEnabled(const bool on);
bool getTimerEnabled(void) const; bool getTimerEnabled(void) const;
uint64_t getRaw(void) const; uint64_t getRaw(void) const;
void setRaw(const uint64_t new_code); void setRaw(const uint64_t new_code);
static uint8_t convertMode(const stdAc::opmode_t mode); static uint8_t convertMode(const stdAc::opmode_t mode);
static uint8_t convertFan(const stdAc::fanspeed_t fan); static uint8_t convertFan(const stdAc::fanspeed_t fan);
static stdAc::opmode_t toCommonMode(const uint8_t mode); static stdAc::opmode_t toCommonMode(const uint8_t mode);
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed); static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
stdAc::state_t toCommon(const stdAc::state_t *prev = nullptr) const; stdAc::state_t toCommon(const stdAc::state_t *prev = nullptr) const;
String toString(void) const; String toString(void) const;
private: private:
@ -166,5 +139,4 @@ class IRKelonAc {
uint8_t _previousTemp = kKelonMinTemp; uint8_t _previousTemp = kKelonMinTemp;
uint8_t _previousFan = kKelonFanAuto; uint8_t _previousFan = kKelonFanAuto;
}; };
#endif // IR_KELON_H_ #endif // IR_KELON_H_

View File

@ -53,6 +53,7 @@ using irutils::addLabeledString;
using irutils::addModeToString; using irutils::addModeToString;
using irutils::addFanToString; using irutils::addFanToString;
using irutils::addTempToString; using irutils::addTempToString;
using irutils::addSwingVToString;
#if SEND_KELVINATOR #if SEND_KELVINATOR
/// Send a Kelvinator A/C message. /// Send a Kelvinator A/C message.
@ -274,16 +275,47 @@ void IRKelvinatorAC::setMode(const uint8_t mode) {
} }
} }
/// Control the current vertical swing setting. /// Set the Vertical Swing mode of the A/C.
/// @param[in] on The desired setting. /// @param[in] automatic Do we use the automatic setting?
void IRKelvinatorAC::setSwingVertical(const bool on) { /// @param[in] position The position/mode to set the vanes to.
_.SwingV = on; void IRKelvinatorAC::setSwingVertical(const bool automatic,
_.VentSwing = (on || _.SwingH); const uint8_t position) {
_.SwingAuto = (automatic || _.SwingH);
uint8_t new_position = position;
if (!automatic) {
switch (position) {
case kKelvinatorSwingVHighest:
case kKelvinatorSwingVUpperMiddle:
case kKelvinatorSwingVMiddle:
case kKelvinatorSwingVLowerMiddle:
case kKelvinatorSwingVLowest:
break;
default:
new_position = kKelvinatorSwingVOff;
}
} else {
switch (position) {
case kKelvinatorSwingVAuto:
case kKelvinatorSwingVLowAuto:
case kKelvinatorSwingVMiddleAuto:
case kKelvinatorSwingVHighAuto:
break;
default:
new_position = kKelvinatorSwingVAuto;
}
}
_.SwingV = new_position;
} }
/// Is the vertical swing setting on? /// Get the Vertical Swing Automatic mode setting of the A/C.
/// @return The current value. /// @return true, the setting is on. false, the setting is off.
bool IRKelvinatorAC::getSwingVertical(void) const { bool IRKelvinatorAC::getSwingVerticalAuto(void) const {
return _.SwingV & 0b0001;
}
/// Get the Vertical Swing position setting of the A/C.
/// @return The native position/mode.
uint8_t IRKelvinatorAC::getSwingVerticalPosition(void) const {
return _.SwingV; return _.SwingV;
} }
@ -291,7 +323,7 @@ bool IRKelvinatorAC::getSwingVertical(void) const {
/// @param[in] on The desired setting. /// @param[in] on The desired setting.
void IRKelvinatorAC::setSwingHorizontal(const bool on) { void IRKelvinatorAC::setSwingHorizontal(const bool on) {
_.SwingH = on; _.SwingH = on;
_.VentSwing = (on || _.SwingV); _.SwingAuto = (on || (_.SwingV & 0b0001));
} }
/// Is the horizontal swing setting on? /// Is the horizontal swing setting on?
@ -378,6 +410,20 @@ uint8_t IRKelvinatorAC::convertMode(const stdAc::opmode_t mode) {
} }
} }
/// Convert a stdAc::swingv_t enum into it's native setting.
/// @param[in] swingv The enum to be converted.
/// @return The native equivalent of the enum.
uint8_t IRKelvinatorAC::convertSwingV(const stdAc::swingv_t swingv) {
switch (swingv) {
case stdAc::swingv_t::kHighest: return kKelvinatorSwingVHighest;
case stdAc::swingv_t::kHigh: return kKelvinatorSwingVHighAuto;
case stdAc::swingv_t::kMiddle: return kKelvinatorSwingVMiddle;
case stdAc::swingv_t::kLow: return kKelvinatorSwingVLowAuto;
case stdAc::swingv_t::kLowest: return kKelvinatorSwingVLowest;
default: return kKelvinatorSwingVAuto;
}
}
/// Convert a native mode to it's stdAc::opmode_t equivalent. /// Convert a native mode to it's stdAc::opmode_t equivalent.
/// @param[in] mode A native operating mode value. /// @param[in] mode A native operating mode value.
/// @return The stdAc::opmode_t equivalent. /// @return The stdAc::opmode_t equivalent.
@ -401,7 +447,7 @@ stdAc::fanspeed_t IRKelvinatorAC::toCommonFanSpeed(const uint8_t speed) {
/// Convert the internal A/C object state to it's stdAc::state_t equivalent. /// Convert the internal A/C object state to it's stdAc::state_t equivalent.
/// @return A stdAc::state_t containing the current settings. /// @return A stdAc::state_t containing the current settings.
stdAc::state_t IRKelvinatorAC::toCommon(void) const { stdAc::state_t IRKelvinatorAC::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::KELVINATOR; result.protocol = decode_type_t::KELVINATOR;
result.model = -1; // Unused. result.model = -1; // Unused.
result.power = _.Power; result.power = _.Power;
@ -442,7 +488,17 @@ String IRKelvinatorAC::toString(void) const {
result += addBoolToString(_.IonFilter, kIonStr); result += addBoolToString(_.IonFilter, kIonStr);
result += addBoolToString(_.Light, kLightStr); result += addBoolToString(_.Light, kLightStr);
result += addBoolToString(_.SwingH, kSwingHStr); result += addBoolToString(_.SwingH, kSwingHStr);
result += addBoolToString(_.SwingV, kSwingVStr); result += addSwingVToString(_.SwingV, kKelvinatorSwingVAuto,
kKelvinatorSwingVHighest,
kKelvinatorSwingVHighAuto,
kKelvinatorSwingVUpperMiddle,
kKelvinatorSwingVMiddle,
kKelvinatorSwingVLowerMiddle,
kKelvinatorSwingVLowAuto,
kKelvinatorSwingVLowest,
kKelvinatorSwingVOff,
kKelvinatorSwingVAuto, kKelvinatorSwingVAuto,
kKelvinatorSwingVAuto);
return result; return result;
} }

View File

@ -14,6 +14,7 @@
// Brand: Kelvinator, Model: KSV70HRC A/C // Brand: Kelvinator, Model: KSV70HRC A/C
// Brand: Kelvinator, Model: KSV80HRC A/C // Brand: Kelvinator, Model: KSV80HRC A/C
// Brand: Green, Model: YAPOF3 remote // Brand: Green, Model: YAPOF3 remote
// Brand: Gree, Model: YAP0F8 remote
// Brand: Sharp, Model: YB1FA remote // Brand: Sharp, Model: YB1FA remote
// Brand: Sharp, Model: A5VEY A/C // Brand: Sharp, Model: A5VEY A/C
@ -39,7 +40,7 @@ union KelvinatorProtocol{
uint8_t Mode :3; uint8_t Mode :3;
uint8_t Power :1; uint8_t Power :1;
uint8_t BasicFan :2; uint8_t BasicFan :2;
uint8_t VentSwing :1; uint8_t SwingAuto :1;
uint8_t :1; // Sleep Modes 1 & 3 (1 = On, 0 = Off) uint8_t :1; // Sleep Modes 1 & 3 (1 = On, 0 = Off)
// Byte 1 // Byte 1
uint8_t Temp :4; // Degrees C. uint8_t Temp :4; // Degrees C.
@ -56,8 +57,7 @@ union KelvinatorProtocol{
uint8_t :2; // End of command block (B01) uint8_t :2; // End of command block (B01)
// (B010 marker and a gap of 20ms) // (B010 marker and a gap of 20ms)
// Byte 4 // Byte 4
uint8_t SwingV :1; uint8_t SwingV :4;
uint8_t :3;
uint8_t SwingH :1; uint8_t SwingH :1;
uint8_t :3; uint8_t :3;
// Byte 5~6 // Byte 5~6
@ -103,6 +103,17 @@ const uint8_t kKelvinatorMinTemp = 16; // 16C
const uint8_t kKelvinatorMaxTemp = 30; // 30C const uint8_t kKelvinatorMaxTemp = 30; // 30C
const uint8_t kKelvinatorAutoTemp = 25; // 25C const uint8_t kKelvinatorAutoTemp = 25; // 25C
const uint8_t kKelvinatorSwingVOff = 0b0000; // 0
const uint8_t kKelvinatorSwingVAuto = 0b0001; // 1
const uint8_t kKelvinatorSwingVHighest = 0b0010; // 2
const uint8_t kKelvinatorSwingVUpperMiddle = 0b0011; // 3
const uint8_t kKelvinatorSwingVMiddle = 0b0100; // 4
const uint8_t kKelvinatorSwingVLowerMiddle = 0b0101; // 5
const uint8_t kKelvinatorSwingVLowest = 0b0110; // 6
const uint8_t kKelvinatorSwingVLowAuto = 0b0111; // 7
const uint8_t kKelvinatorSwingVMiddleAuto = 0b1001; // 9
const uint8_t kKelvinatorSwingVHighAuto = 0b1011; // 11
// Legacy defines (Deprecated) // Legacy defines (Deprecated)
#define KELVINATOR_MIN_TEMP kKelvinatorMinTemp #define KELVINATOR_MIN_TEMP kKelvinatorMinTemp
#define KELVINATOR_MAX_TEMP kKelvinatorMaxTemp #define KELVINATOR_MAX_TEMP kKelvinatorMaxTemp
@ -142,8 +153,11 @@ class IRKelvinatorAC {
uint8_t getFan(void) const; uint8_t getFan(void) const;
void setMode(const uint8_t mode); void setMode(const uint8_t mode);
uint8_t getMode(void) const; uint8_t getMode(void) const;
void setSwingVertical(const bool on); void setSwingVertical(const bool automatic, const uint8_t position);
bool getSwingVertical(void) const; bool getSwingVerticalAuto(void) const;
uint8_t getSwingVerticalPosition(void) const;
static uint8_t convertSwingV(const stdAc::swingv_t swingv);
static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
void setSwingHorizontal(const bool on); void setSwingHorizontal(const bool on);
bool getSwingHorizontal(void) const; bool getSwingHorizontal(void) const;
void setQuiet(const bool on); void setQuiet(const bool on);

View File

@ -22,6 +22,7 @@ using irutils::addModeToString;
using irutils::addModelToString; using irutils::addModelToString;
using irutils::addFanToString; using irutils::addFanToString;
using irutils::addTempToString; using irutils::addTempToString;
using irutils::addToggleToString;
using irutils::addSwingVToString; using irutils::addSwingVToString;
using irutils::addIntToString; using irutils::addIntToString;
@ -255,6 +256,11 @@ void IRLgAc::send(const uint16_t repeat) {
_irsend.send(_protocol, getRaw(), kLgBits, repeat); _irsend.send(_protocol, getRaw(), kLgBits, repeat);
// Some models have extra/special settings & controls // Some models have extra/special settings & controls
switch (getModel()) { switch (getModel()) {
case lg_ac_remote_model_t::LG6711A20083V:
// Only send the swing setting if we need to.
if (_swingv != _swingv_prev)
_irsend.send(_protocol, _swingv, kLgBits, repeat);
break;
case lg_ac_remote_model_t::AKB74955603: case lg_ac_remote_model_t::AKB74955603:
// Only send the swing setting if we need to. // Only send the swing setting if we need to.
if (_swingv != _swingv_prev) if (_swingv != _swingv_prev)
@ -309,6 +315,7 @@ void IRLgAc::setModel(const lg_ac_remote_model_t model) {
_protocol = decode_type_t::LG2; _protocol = decode_type_t::LG2;
break; break;
case lg_ac_remote_model_t::GE6711AR2853M: case lg_ac_remote_model_t::GE6711AR2853M:
case lg_ac_remote_model_t::LG6711A20083V:
_protocol = decode_type_t::LG; _protocol = decode_type_t::LG;
break; break;
default: default:
@ -319,24 +326,25 @@ void IRLgAc::setModel(const lg_ac_remote_model_t model) {
/// Get the model of the A/C. /// Get the model of the A/C.
/// @return The enum of the compatible model. /// @return The enum of the compatible model.
lg_ac_remote_model_t IRLgAc::getModel(void) const { lg_ac_remote_model_t IRLgAc::getModel(void) const { return _model; }
return _model;
}
/// Check if the stored code must belong to a AKB74955603 model. /// Check if the stored code must belong to a AKB74955603 model.
/// @return true, if it is AKB74955603 message. Otherwise, false. /// @return true, if it is AKB74955603 message. Otherwise, false.
/// @note Internal use only. /// @note Internal use only.
bool IRLgAc::_isAKB74955603(void) const { bool IRLgAc::_isAKB74955603(void) const {
return ((_.raw & kLgAcAKB74955603DetectionMask) && _isNormal()) || return ((_.raw & kLgAcAKB74955603DetectionMask) && _isNormal()) ||
isSwingV() || isLightToggle(); (isSwingV() && !isSwingVToggle()) || isLightToggle();
} }
/// Check if the stored code must belong to a AKB73757604 model. /// Check if the stored code must belong to a AKB73757604 model.
/// @return true, if it is AKB73757604 message. Otherwise, false. /// @return true, if it is AKB73757604 message. Otherwise, false.
/// @note Internal use only. /// @note Internal use only.
bool IRLgAc::_isAKB73757604(void) const { bool IRLgAc::_isAKB73757604(void) const { return isSwingH() || isVaneSwingV(); }
return isSwingH() || isVaneSwingV();
} /// Check if the stored code must belong to a LG6711A20083V model.
/// @return true, if it is LG6711A20083V message. Otherwise, false.
/// @note Internal use only.
bool IRLgAc::_isLG6711A20083V(void) const { return isSwingVToggle(); }
/// Get a copy of the internal state/code for this protocol. /// Get a copy of the internal state/code for this protocol.
/// @return The code for this protocol based on the current internal state. /// @return The code for this protocol based on the current internal state.
@ -353,7 +361,10 @@ void IRLgAc::setRaw(const uint32_t new_code, const decode_type_t protocol) {
// Set the default model for this protocol, if the protocol is supplied. // Set the default model for this protocol, if the protocol is supplied.
switch (protocol) { switch (protocol) {
case decode_type_t::LG: case decode_type_t::LG:
setModel(lg_ac_remote_model_t::GE6711AR2853M); if (isSwingVToggle()) // This model uses a swingv toggle message.
setModel(lg_ac_remote_model_t::LG6711A20083V);
else // Assume others are a different model.
setModel(lg_ac_remote_model_t::GE6711AR2853M);
break; break;
case decode_type_t::LG2: case decode_type_t::LG2:
setModel(lg_ac_remote_model_t::AKB75215403); setModel(lg_ac_remote_model_t::AKB75215403);
@ -521,18 +532,22 @@ void IRLgAc::setMode(const uint8_t mode) {
} }
} }
/// Check if the stored code is a SwingV Toggle message.
/// @return true, if it is. Otherwise, false.
bool IRLgAc::isSwingVToggle(void) const { return _.raw == kLgAcSwingVToggle; }
/// Check if the stored code is a Swing message. /// Check if the stored code is a Swing message.
/// @return true, if it is. Otherwise, false. /// @return true, if it is. Otherwise, false.
bool IRLgAc::isSwing(void) const { bool IRLgAc::isSwing(void) const {
return (_.raw >> 12) == kLgAcSwingSignature; return ((_.raw >> 12) == kLgAcSwingSignature) || isSwingVToggle();
} }
/// Check if the stored code is a non-vane SwingV message. /// Check if the stored code is a non-vane SwingV message.
/// @return true, if it is. Otherwise, false. /// @return true, if it is. Otherwise, false.
bool IRLgAc::isSwingV(void) const { bool IRLgAc::isSwingV(void) const {
const uint32_t code = _.raw >> kLgAcChecksumSize; const uint32_t code = _.raw >> kLgAcChecksumSize;
return code >= (kLgAcSwingVLowest >> kLgAcChecksumSize) && return (code >= (kLgAcSwingVLowest >> kLgAcChecksumSize) &&
code < (kLgAcSwingHAuto >> kLgAcChecksumSize); code < (kLgAcSwingHAuto >> kLgAcChecksumSize)) || isSwingVToggle();
} }
/// Check if the stored code is a SwingH message. /// Check if the stored code is a SwingH message.
@ -562,7 +577,7 @@ bool IRLgAc::isVaneSwingV(void) const {
/// @param[in] position The position/mode to set the vanes to. /// @param[in] position The position/mode to set the vanes to.
void IRLgAc::setSwingV(const uint32_t position) { void IRLgAc::setSwingV(const uint32_t position) {
// Is it a valid position code? // Is it a valid position code?
if (position == kLgAcSwingVOff || if (position == kLgAcSwingVOff || position == kLgAcSwingVToggle ||
toCommonSwingV(position) != stdAc::swingv_t::kOff) { toCommonSwingV(position) != stdAc::swingv_t::kOff) {
if (position <= 0xFF) { // It's a short code, convert it. if (position <= 0xFF) { // It's a short code, convert it.
_swingv = (kLgAcSwingSignature << 8 | position) << kLgAcChecksumSize; _swingv = (kLgAcSwingSignature << 8 | position) << kLgAcChecksumSize;
@ -703,6 +718,7 @@ stdAc::swingv_t IRLgAc::toCommonSwingV(const uint32_t code) {
case kLgAcSwingVLow: return stdAc::swingv_t::kLow; case kLgAcSwingVLow: return stdAc::swingv_t::kLow;
case kLgAcSwingVLowest_Short: case kLgAcSwingVLowest_Short:
case kLgAcSwingVLowest: return stdAc::swingv_t::kLowest; case kLgAcSwingVLowest: return stdAc::swingv_t::kLowest;
case kLgAcSwingVToggle:
case kLgAcSwingVSwing_Short: case kLgAcSwingVSwing_Short:
case kLgAcSwingVSwing: return stdAc::swingv_t::kAuto; case kLgAcSwingVSwing: return stdAc::swingv_t::kAuto;
default: return stdAc::swingv_t::kOff; default: return stdAc::swingv_t::kOff;
@ -740,7 +756,7 @@ uint8_t IRLgAc::convertVaneSwingV(const stdAc::swingv_t swingv) {
/// @param[in] prev Ptr to the previous state if required. /// @param[in] prev Ptr to the previous state if required.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRLgAc::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRLgAc::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
// Start with the previous state if given it. // Start with the previous state if given it.
if (prev != NULL) { if (prev != NULL) {
result = *prev; result = *prev;
@ -752,13 +768,18 @@ stdAc::state_t IRLgAc::toCommon(const stdAc::state_t *prev) const {
result.swingv = toCommonSwingV(getSwingV()); result.swingv = toCommonSwingV(getSwingV());
} }
result.protocol = _protocol; result.protocol = _protocol;
if (isLightToggle()) {
result.light = !result.light;
return result;
} else {
result.light = _light;
}
result.model = getModel(); result.model = getModel();
result.power = getPower(); result.power = getPower();
result.mode = toCommonMode(_.Mode); result.mode = toCommonMode(_.Mode);
result.celsius = true; result.celsius = true;
result.degrees = getTemp(); result.degrees = getTemp();
result.fanspeed = toCommonFanSpeed(_.Fan); result.fanspeed = toCommonFanSpeed(_.Fan);
result.light = isLightToggle() ? !result.light : _light;
if (isSwingV()) result.swingv = toCommonSwingV(getSwingV()); if (isSwingV()) result.swingv = toCommonSwingV(getSwingV());
if (isVaneSwingV()) if (isVaneSwingV())
result.swingv = toCommonVaneSwingV(VANESWINGVPOS(getVaneCode(_.raw))); result.swingv = toCommonVaneSwingV(VANESWINGVPOS(getVaneCode(_.raw)));
@ -800,18 +821,21 @@ String IRLgAc::toString(void) const {
} else if (isSwingH()) { } else if (isSwingH()) {
result += addBoolToString(_swingh, kSwingHStr); result += addBoolToString(_swingh, kSwingHStr);
} else if (isSwingV()) { } else if (isSwingV()) {
result += addSwingVToString((uint8_t)(_swingv >> kLgAcChecksumSize), if (isSwingVToggle())
0, // No Auto, See "swing". Unused result += addToggleToString(isSwingVToggle(), kSwingVStr);
kLgAcSwingVHighest_Short, else
kLgAcSwingVHigh_Short, result += addSwingVToString((uint8_t)(_swingv >> kLgAcChecksumSize),
kLgAcSwingVUpperMiddle_Short, 0, // No Auto, See "swing". Unused
kLgAcSwingVMiddle_Short, kLgAcSwingVHighest_Short,
0, // Unused kLgAcSwingVHigh_Short,
kLgAcSwingVLow_Short, kLgAcSwingVUpperMiddle_Short,
kLgAcSwingVLowest_Short, kLgAcSwingVMiddle_Short,
kLgAcSwingVOff_Short, 0, // Unused
kLgAcSwingVSwing_Short, kLgAcSwingVLow_Short,
0, 0); kLgAcSwingVLowest_Short,
kLgAcSwingVOff_Short,
kLgAcSwingVSwing_Short,
0, 0);
} else if (isVaneSwingV()) { } else if (isVaneSwingV()) {
const uint8_t vane = getVaneCode(_.raw) / kLgAcVaneSwingVSize; const uint8_t vane = getVaneCode(_.raw) / kLgAcVaneSwingVSize;
result += addIntToString(vane, kVaneStr); result += addIntToString(vane, kVaneStr);

View File

@ -6,7 +6,8 @@
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1513 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1513
// Supports: // Supports:
// Brand: LG, Model: 6711A20083V remote (LG) // Brand: LG, Model: 6711A20083V remote (LG - LG6711A20083V)
// Brand: LG, Model: TS-H122ERM1 remote (LG - LG6711A20083V)
// Brand: LG, Model: AKB74395308 remote (LG2) // Brand: LG, Model: AKB74395308 remote (LG2)
// Brand: LG, Model: S4-W12JA3AA A/C (LG2) // Brand: LG, Model: S4-W12JA3AA A/C (LG2)
// Brand: LG, Model: AKB75215403 remote (LG2) // Brand: LG, Model: AKB75215403 remote (LG2)
@ -17,8 +18,8 @@
// Brand: LG, Model: AKB73757604 remote (LG2 - AKB73757604) // Brand: LG, Model: AKB73757604 remote (LG2 - AKB73757604)
// Brand: LG, Model: AKB73315611 remote (LG2 - AKB74955603) // Brand: LG, Model: AKB73315611 remote (LG2 - AKB74955603)
// Brand: LG, Model: MS05SQ NW0 A/C (LG2 - AKB74955603) // Brand: LG, Model: MS05SQ NW0 A/C (LG2 - AKB74955603)
// Brand: General Electric, Model: AG1BH09AW101 Split A/C (LG) // Brand: General Electric, Model: AG1BH09AW101 A/C (LG - GE6711AR2853M)
// Brand: General Electric, Model: 6711AR2853M A/C Remote (LG) // Brand: General Electric, Model: 6711AR2853M Remote (LG - GE6711AR2853M)
#ifndef IR_LG_H_ #ifndef IR_LG_H_
#define IR_LG_H_ #define IR_LG_H_
@ -73,6 +74,7 @@ const uint8_t kLgAcSignature = 0x88;
const uint32_t kLgAcOffCommand = 0x88C0051; const uint32_t kLgAcOffCommand = 0x88C0051;
const uint32_t kLgAcLightToggle = 0x88C00A6; const uint32_t kLgAcLightToggle = 0x88C00A6;
const uint32_t kLgAcSwingVToggle = 0x8810001;
const uint32_t kLgAcSwingSignature = 0x8813; const uint32_t kLgAcSwingSignature = 0x8813;
const uint32_t kLgAcSwingVLowest = 0x8813048; const uint32_t kLgAcSwingVLowest = 0x8813048;
const uint32_t kLgAcSwingVLow = 0x8813059; const uint32_t kLgAcSwingVLow = 0x8813059;
@ -144,6 +146,7 @@ class IRLgAc {
void setSwingH(const bool on); void setSwingH(const bool on);
bool getSwingH(void) const; bool getSwingH(void) const;
bool isSwingV(void) const; bool isSwingV(void) const;
bool isSwingVToggle(void) const;
bool isVaneSwingV(void) const; bool isVaneSwingV(void) const;
void setSwingV(const uint32_t position); void setSwingV(const uint32_t position);
uint32_t getSwingV(void) const; uint32_t getSwingV(void) const;
@ -192,6 +195,7 @@ class IRLgAc {
void _setTemp(const uint8_t value); void _setTemp(const uint8_t value);
bool _isAKB74955603(void) const; bool _isAKB74955603(void) const;
bool _isAKB73757604(void) const; bool _isAKB73757604(void) const;
bool _isLG6711A20083V(void) const;
bool _isNormal(void) const; bool _isNormal(void) const;
}; };

View File

@ -42,6 +42,7 @@ using irutils::addIntToString;
using irutils::addLabeledString; using irutils::addLabeledString;
using irutils::addModeToString; using irutils::addModeToString;
using irutils::addTempToString; using irutils::addTempToString;
using irutils::addToggleToString;
using irutils::minsToString; using irutils::minsToString;
#if SEND_MIDEA #if SEND_MIDEA
@ -100,10 +101,13 @@ IRMideaAC::IRMideaAC(const uint16_t pin, const bool inverted,
void IRMideaAC::stateReset(void) { void IRMideaAC::stateReset(void) {
// Power On, Mode Auto, Fan Auto, Temp = 25C/77F // Power On, Mode Auto, Fan Auto, Temp = 25C/77F
_.remote_state = 0xA1826FFFFF62; _.remote_state = 0xA1826FFFFF62;
_SwingVToggle = false; _CleanToggle = false;
_EconoToggle = false; _EconoToggle = false;
_TurboToggle = false; _8CHeatToggle = false;
_LightToggle = false; _LightToggle = false;
_Quiet = _Quiet_prev = false;
_SwingVToggle = false;
_TurboToggle = false;
#if KAYSUN_AC #if KAYSUN_AC
_SwingVStep = false; _SwingVStep = false;
#endif // KAYSUN_AC #endif // KAYSUN_AC
@ -135,6 +139,19 @@ void IRMideaAC::send(const uint16_t repeat) {
if (_LightToggle && !isLightToggle()) if (_LightToggle && !isLightToggle())
_irsend.sendMidea(kMideaACToggleLight, kMideaBits, repeat); _irsend.sendMidea(kMideaACToggleLight, kMideaBits, repeat);
_LightToggle = false; _LightToggle = false;
if (getMode() <= kMideaACAuto) { // Only available in Cool, Dry, or Auto mode
if (_CleanToggle && !isCleanToggle())
_irsend.sendMidea(kMideaACToggleSelfClean, kMideaBits, repeat);
_CleanToggle = false;
} else if (getMode() == kMideaACHeat) { // Only available in Heat mode
if (_8CHeatToggle && !is8CHeatToggle())
_irsend.sendMidea(kMideaACToggle8CHeat, kMideaBits, repeat);
_8CHeatToggle = false;
}
if (_Quiet != _Quiet_prev)
_irsend.sendMidea(_Quiet ? kMideaACQuietOn : kMideaACQuietOff,
kMideaBits, repeat);
_Quiet_prev = _Quiet;
} }
#endif // SEND_MIDEA #endif // SEND_MIDEA
@ -410,6 +427,75 @@ bool IRMideaAC::getLightToggle(void) {
return _LightToggle; return _LightToggle;
} }
/// Is the current state a Self-Clean toggle message?
/// @return true, it is. false, it isn't.
bool IRMideaAC::isCleanToggle(void) const {
return _.remote_state == kMideaACToggleSelfClean;
}
/// Set the A/C to toggle the Self Clean mode for the next send.
/// @note Only works in Cool, Dry, or Auto modes.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRMideaAC::setCleanToggle(const bool on) {
_CleanToggle = on && getMode() <= kMideaACAuto;
}
// Get the Self-Clean toggle state of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRMideaAC::getCleanToggle(void) {
_CleanToggle |= isCleanToggle();
return _CleanToggle;
}
/// Is the current state a 8C Heat (Freeze Protect) toggle message?
/// @note Only works in Heat mode.
/// @return true, it is. false, it isn't.
bool IRMideaAC::is8CHeatToggle(void) const {
return _.remote_state == kMideaACToggle8CHeat;
}
/// Set the A/C to toggle the 8C Heat (Freeze Protect) mode for the next send.
/// @note Only works in Heat mode.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRMideaAC::set8CHeatToggle(const bool on) {
_8CHeatToggle = on && getMode() == kMideaACHeat;
}
// Get the 8C Heat (Freeze Protect) toggle state of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRMideaAC::get8CHeatToggle(void) {
_8CHeatToggle |= is8CHeatToggle();
return _8CHeatToggle;
}
/// Is the current state a Quiet(Silent) message?
/// @return true, it is. false, it isn't.
bool IRMideaAC::isQuiet(void) const {
return (_.remote_state == kMideaACQuietOff ||
_.remote_state == kMideaACQuietOn);
}
/// Set the Quiet (Silent) mode for the next send.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRMideaAC::setQuiet(const bool on) { _Quiet = on; }
/// Set the Quiet (Silent) mode for the next send.
/// @param[in] on true, the setting is on. false, the setting is off.
/// @param[in] prev true, previously the setting was on. false, setting was off.
void IRMideaAC::setQuiet(const bool on, const bool prev) {
setQuiet(on);
_Quiet_prev = prev;
}
// Get the Quiet (Silent) mode state of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRMideaAC::getQuiet(void) const {
if (isQuiet())
return _.remote_state == kMideaACQuietOn;
else
return _Quiet;
}
/// Calculate the checksum for a given state. /// Calculate the checksum for a given state.
/// @param[in] state The value to calc the checksum of. /// @param[in] state The value to calc the checksum of.
/// @return The calculated checksum value. /// @return The calculated checksum value.
@ -566,7 +652,7 @@ stdAc::fanspeed_t IRMideaAC::toCommonFanSpeed(const uint8_t speed) {
/// @param[in] prev A Ptr to the previous state. /// @param[in] prev A Ptr to the previous state.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) { stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) {
stdAc::state_t result; stdAc::state_t result{};
if (prev != NULL) { if (prev != NULL) {
result = *prev; result = *prev;
} else { } else {
@ -577,7 +663,6 @@ stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) {
result.swingv = stdAc::swingv_t::kOff; result.swingv = stdAc::swingv_t::kOff;
result.quiet = false; result.quiet = false;
result.turbo = false; result.turbo = false;
result.clean = false;
result.econo = false; result.econo = false;
result.filter = false; result.filter = false;
result.light = false; result.light = false;
@ -597,6 +682,7 @@ stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) {
result.fanspeed = toCommonFanSpeed(_.Fan); result.fanspeed = toCommonFanSpeed(_.Fan);
result.sleep = _.Sleep ? 0 : -1; result.sleep = _.Sleep ? 0 : -1;
result.econo = getEconoToggle(); result.econo = getEconoToggle();
result.clean ^= getCleanToggle();
return result; return result;
} }
@ -612,7 +698,7 @@ String IRMideaAC::toString(void) {
case kMideaACTypeCommand: result += kCommandStr; break; case kMideaACTypeCommand: result += kCommandStr; break;
case kMideaACTypeSpecial: result += kSpecialStr; break; case kMideaACTypeSpecial: result += kSpecialStr; break;
case kMideaACTypeFollow: result += kFollowStr; break; case kMideaACTypeFollow: result += kFollowStr; break;
default: result += kUnknownStr; default: result += kUnknownStr;
} }
result += ')'; result += ')';
if (message_type != kMideaACTypeSpecial) { if (message_type != kMideaACTypeSpecial) {
@ -643,13 +729,16 @@ String IRMideaAC::toString(void) {
kMideaACFanAuto, kMideaACFanAuto, kMideaACFanMed); kMideaACFanAuto, kMideaACFanAuto, kMideaACFanMed);
result += addBoolToString(_.Sleep, kSleepStr); result += addBoolToString(_.Sleep, kSleepStr);
} }
result += addBoolToString(getSwingVToggle(), kSwingVToggleStr); result += addToggleToString(getSwingVToggle(), kSwingVStr);
#if KAYSUN_AC #if KAYSUN_AC
result += addBoolToString(getSwingVStep(), kStepStr); result += addBoolToString(getSwingVStep(), kStepStr);
#endif // KAYSUN_AC #endif // KAYSUN_AC
result += addBoolToString(getEconoToggle(), kEconoToggleStr); result += addToggleToString(getEconoToggle(), kEconoStr);
result += addBoolToString(getTurboToggle(), kTurboToggleStr); result += addToggleToString(getTurboToggle(), kTurboStr);
result += addBoolToString(getLightToggle(), kLightToggleStr); result += addBoolToString(getQuiet(), kQuietStr);
result += addToggleToString(getLightToggle(), kLightStr);
result += addToggleToString(getCleanToggle(), kCleanStr);
result += addToggleToString(get8CHeatToggle(), k8CHeatStr);
return result; return result;
} }

View File

@ -5,6 +5,7 @@
/// Midea added by crankyoldgit & bwze /// Midea added by crankyoldgit & bwze
/// @see https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing /// @see https://docs.google.com/spreadsheets/d/1TZh4jWrx4h9zzpYUI9aYXMl1fYOiqu-xVuOOMqagxrs/edit?usp=sharing
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1342#issuecomment-733721085 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1342#issuecomment-733721085
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1733
// Supports: // Supports:
// Brand: Pioneer System, Model: RYBO12GMFILCAD A/C (12K BTU) (MIDEA) // Brand: Pioneer System, Model: RYBO12GMFILCAD A/C (12K BTU) (MIDEA)
@ -24,6 +25,18 @@
// Brand: Danby, Model: R09C/BCGE remote (MIDEA) // Brand: Danby, Model: R09C/BCGE remote (MIDEA)
// Brand: Trotec, Model: TROTEC PAC 3900 X (MIDEA) // Brand: Trotec, Model: TROTEC PAC 3900 X (MIDEA)
// Brand: Trotec, Model: RG57H(B)/BGE remote (MIDEA) // Brand: Trotec, Model: RG57H(B)/BGE remote (MIDEA)
// Brand: Lennox, Model: RG57A6/BGEFU1 remote (MIDEA)
// Brand: Lennox, Model: MWMA009S4-3P A/C (MIDEA)
// Brand: Lennox, Model: MWMA012S4-3P A/C (MIDEA)
// Brand: Lennox, Model: MCFA indoor split A/C (MIDEA)
// Brand: Lennox, Model: MCFB indoor split A/C (MIDEA)
// Brand: Lennox, Model: MMDA indoor split A/C (MIDEA)
// Brand: Lennox, Model: MMDB indoor split A/C (MIDEA)
// Brand: Lennox, Model: MWMA indoor split A/C (MIDEA)
// Brand: Lennox, Model: MWMB indoor split A/C (MIDEA)
// Brand: Lennox, Model: M22A indoor split A/C (MIDEA)
// Brand: Lennox, Model: M33A indoor split A/C (MIDEA)
// Brand: Lennox, Model: M33B indoor split A/C (MIDEA)
#ifndef IR_MIDEA_H_ #ifndef IR_MIDEA_H_
#define IR_MIDEA_H_ #define IR_MIDEA_H_
@ -123,9 +136,16 @@ const uint8_t kMideaACFanHigh = 3; // 0b11
// const uint64_t kMideaACToggleIonizer = 0xA201FFFFFF7C; // const uint64_t kMideaACToggleIonizer = 0xA201FFFFFF7C;
kSwingVToggleStr = kIonStr; kSwingVToggleStr = kIonStr;
#endif // DANBY_DAC #endif // DANBY_DAC
const uint64_t kMideaACToggleEcono = 0xA202FFFFFF7E; const uint64_t kMideaACToggleEcono = 0xA202FFFFFF7E;
const uint64_t kMideaACToggleLight = 0xA208FFFFFF75; const uint64_t kMideaACToggleLight = 0xA208FFFFFF75;
const uint64_t kMideaACToggleTurbo = 0xA209FFFFFF74; const uint64_t kMideaACToggleTurbo = 0xA209FFFFFF74;
// Mode must be Auto, Cool, or Dry
const uint64_t kMideaACToggleSelfClean = 0xA20DFFFFFF70;
// 8C Heat AKA Freeze Protection
const uint64_t kMideaACToggle8CHeat = 0xA20FFFFFFF73; // Only in Heat
const uint64_t kMideaACQuietOn = 0xA212FFFFFF6E;
const uint64_t kMideaACQuietOff = 0xA213FFFFFF6F;
const uint8_t kMideaACTypeCommand = 0b001; ///< Message type const uint8_t kMideaACTypeCommand = 0b001; ///< Message type
const uint8_t kMideaACTypeSpecial = 0b010; ///< Message type const uint8_t kMideaACTypeSpecial = 0b010; ///< Message type
const uint8_t kMideaACTypeFollow = 0b100; ///< Message type const uint8_t kMideaACTypeFollow = 0b100; ///< Message type
@ -202,6 +222,16 @@ class IRMideaAC {
bool isLightToggle(void) const; bool isLightToggle(void) const;
void setLightToggle(const bool on); void setLightToggle(const bool on);
bool getLightToggle(void); bool getLightToggle(void);
bool isCleanToggle(void) const;
void setCleanToggle(const bool on);
bool getCleanToggle(void);
bool is8CHeatToggle(void) const;
void set8CHeatToggle(const bool on);
bool get8CHeatToggle(void);
bool isQuiet(void) const;
void setQuiet(const bool on);
void setQuiet(const bool on, const bool prev);
bool getQuiet(void) const;
uint8_t getType(void) const; uint8_t getType(void) const;
bool isOnTimerEnabled(void) const; bool isOnTimerEnabled(void) const;
uint16_t getOnTimer(void) const; uint16_t getOnTimer(void) const;
@ -225,13 +255,17 @@ class IRMideaAC {
/// @endcond /// @endcond
#endif // UNIT_TEST #endif // UNIT_TEST
MideaProtocol _; MideaProtocol _;
bool _CleanToggle;
bool _EconoToggle;
bool _8CHeatToggle;
bool _LightToggle;
bool _Quiet;
bool _Quiet_prev;
bool _SwingVToggle; bool _SwingVToggle;
#if KAYSUN_AC #if KAYSUN_AC
bool _SwingVStep; bool _SwingVStep;
#endif // KAYSUN_AC #endif // KAYSUN_AC
bool _EconoToggle;
bool _TurboToggle; bool _TurboToggle;
bool _LightToggle;
void checksum(void); void checksum(void);
static uint8_t calcChecksum(const uint64_t state); static uint8_t calcChecksum(const uint64_t state);
void setType(const uint8_t type); void setType(const uint8_t type);

View File

@ -733,7 +733,7 @@ stdAc::swingv_t IRMirageAc::toCommonSwingV(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRMirageAc::toCommon(void) const { stdAc::state_t IRMirageAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::MIRAGE; result.protocol = decode_type_t::MIRAGE;
result.model = _model; result.model = _model;
result.power = getPower(); result.power = getPower();

View File

@ -62,7 +62,7 @@ const uint16_t kMitsubishiAcBitMark = 450;
const uint16_t kMitsubishiAcOneSpace = 1300; const uint16_t kMitsubishiAcOneSpace = 1300;
const uint16_t kMitsubishiAcZeroSpace = 420; const uint16_t kMitsubishiAcZeroSpace = 420;
const uint16_t kMitsubishiAcRptMark = 440; const uint16_t kMitsubishiAcRptMark = 440;
const uint16_t kMitsubishiAcRptSpace = 17100; const uint16_t kMitsubishiAcRptSpace = 15500;
const uint8_t kMitsubishiAcExtraTolerance = 5; const uint8_t kMitsubishiAcExtraTolerance = 5;
// Mitsubishi 136 bit A/C // Mitsubishi 136 bit A/C
@ -781,7 +781,7 @@ stdAc::swingh_t IRMitsubishiAC::toCommonSwingH(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRMitsubishiAC::toCommon(void) const { stdAc::state_t IRMitsubishiAC::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::MITSUBISHI_AC; result.protocol = decode_type_t::MITSUBISHI_AC;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;
@ -1195,7 +1195,7 @@ stdAc::swingv_t IRMitsubishi136::toCommonSwingV(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRMitsubishi136::toCommon(void) const { stdAc::state_t IRMitsubishi136::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::MITSUBISHI136; result.protocol = decode_type_t::MITSUBISHI136;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;
@ -1660,7 +1660,7 @@ stdAc::swingh_t IRMitsubishi112::toCommonSwingH(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRMitsubishi112::toCommon(void) const { stdAc::state_t IRMitsubishi112::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::MITSUBISHI112; result.protocol = decode_type_t::MITSUBISHI112;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;

View File

@ -35,6 +35,7 @@
// Brand: Mitsubishi Electric, Model: SG15D remote (MITSUBISHI_AC) // Brand: Mitsubishi Electric, Model: SG15D remote (MITSUBISHI_AC)
// Brand: Mitsubishi Electric, Model: MSZ-ZW4017S A/C (MITSUBISHI_AC) // Brand: Mitsubishi Electric, Model: MSZ-ZW4017S A/C (MITSUBISHI_AC)
// Brand: Mitsubishi Electric, Model: MSZ-FHnnVE A/C (MITSUBISHI_AC) // Brand: Mitsubishi Electric, Model: MSZ-FHnnVE A/C (MITSUBISHI_AC)
// Brand: Mitsubishi Electric, Model: RH151 remote (MITSUBISHI_AC)
#ifndef IR_MITSUBISHI_H_ #ifndef IR_MITSUBISHI_H_
#define IR_MITSUBISHI_H_ #define IR_MITSUBISHI_H_

View File

@ -454,7 +454,7 @@ stdAc::swingv_t IRMitsubishiHeavy152Ac::toCommonSwingV(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRMitsubishiHeavy152Ac::toCommon(void) const { stdAc::state_t IRMitsubishiHeavy152Ac::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::MITSUBISHI_HEAVY_152; result.protocol = decode_type_t::MITSUBISHI_HEAVY_152;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;
@ -899,7 +899,7 @@ stdAc::swingv_t IRMitsubishiHeavy88Ac::toCommonSwingV(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRMitsubishiHeavy88Ac::toCommon(void) const { stdAc::state_t IRMitsubishiHeavy88Ac::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::MITSUBISHI_HEAVY_88; result.protocol = decode_type_t::MITSUBISHI_HEAVY_88;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;

View File

@ -484,7 +484,7 @@ bool IRNeoclimaAc::getFollow(void) const {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRNeoclimaAc::toCommon(void) const { stdAc::state_t IRNeoclimaAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::NEOCLIMA; result.protocol = decode_type_t::NEOCLIMA;
result.model = -1; // No models used. result.model = -1; // No models used.
result.power = _.Power; result.power = _.Power;

View File

@ -760,7 +760,7 @@ stdAc::swingv_t IRPanasonicAc::toCommonSwingV(const uint8_t pos) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRPanasonicAc::toCommon(void) { stdAc::state_t IRPanasonicAc::toCommon(void) {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::PANASONIC_AC; result.protocol = decode_type_t::PANASONIC_AC;
result.model = getModel(); result.model = getModel();
result.power = getPower(); result.power = getPower();
@ -1307,7 +1307,7 @@ String IRPanasonicAc32::toString(void) const {
/// @param[in] prev Ptr to the previous state if required. /// @param[in] prev Ptr to the previous state if required.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRPanasonicAc32::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRPanasonicAc32::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
// Start with the previous state if given it. // Start with the previous state if given it.
if (prev != NULL) { if (prev != NULL) {
result = *prev; result = *prev;

View File

@ -9,6 +9,7 @@
/// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/547 /// @see https://github.com/crankyoldgit/IRremoteESP8266/pull/547
/// @see https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers /// @see https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/IR+Codes/A+V+Receivers
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1220 /// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1220
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1749#issuecomment-1028122645
// Supports: // Supports:
// Brand: Pioneer, Model: AV Receivers // Brand: Pioneer, Model: AV Receivers
@ -74,6 +75,10 @@ void IRsend::sendPioneer(const uint64_t data, const uint16_t nbits,
/// and the second the command. /// and the second the command.
/// e.g. /// e.g.
/// "A556+AF20" is an Address of 0xA556 & a Command of 0xAF20. /// "A556+AF20" is an Address of 0xA556 & a Command of 0xAF20.
/// @note If the Address is 0, use it like the following:
/// `irsend.sendPioneer(irsend.encodePioneer(0, 0xAA1C), 32, 1);` or
/// `irsend.sendPioneer(irsend.encodePioneer(0xAA1C, 0xAA1C), 64, 0);`
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1749#issuecomment-1028122645
uint64_t IRsend::encodePioneer(const uint16_t address, const uint16_t command) { uint64_t IRsend::encodePioneer(const uint16_t address, const uint16_t command) {
return (((uint64_t)encodeNEC(address >> 8, address & 0xFF)) << 32) | return (((uint64_t)encodeNEC(address >> 8, address & 0xFF)) << 32) |
encodeNEC(command >> 8, command & 0xFF); encodeNEC(command >> 8, command & 0xFF);

View File

@ -324,7 +324,7 @@ stdAc::fanspeed_t IRRhossAc::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRRhossAc::toCommon(void) const { stdAc::state_t IRRhossAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::RHOSS; result.protocol = decode_type_t::RHOSS;
result.power = getPower(); result.power = getPower();
result.mode = toCommonMode(_.Mode); result.mode = toCommonMode(_.Mode);

View File

@ -866,7 +866,7 @@ stdAc::fanspeed_t IRSamsungAc::toCommonFanSpeed(const uint8_t spd) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRSamsungAc::toCommon(void) const { stdAc::state_t IRSamsungAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::SAMSUNG_AC; result.protocol = decode_type_t::SAMSUNG_AC;
result.model = -1; // Not supported. result.model = -1; // Not supported.
result.power = getPower(); result.power = getPower();

View File

@ -607,7 +607,7 @@ void IRSanyoAc::setOffTimer(const uint16_t mins) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRSanyoAc::toCommon(void) const { stdAc::state_t IRSanyoAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::SANYO_AC; result.protocol = decode_type_t::SANYO_AC;
result.model = -1; // Not supported. result.model = -1; // Not supported.
result.power = getPower(); result.power = getPower();
@ -935,7 +935,7 @@ bool IRSanyoAc88::getSleep(void) const { return _.Sleep; }
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRSanyoAc88::toCommon(void) const { stdAc::state_t IRSanyoAc88::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::SANYO_AC88; result.protocol = decode_type_t::SANYO_AC88;
result.model = -1; // Not supported. result.model = -1; // Not supported.
result.power = getPower(); result.power = getPower();

View File

@ -837,7 +837,7 @@ stdAc::swingv_t IRSharpAc::toCommonSwingV(const uint8_t pos,
/// @param[in] prev Ptr to the previous state if required. /// @param[in] prev Ptr to the previous state if required.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRSharpAc::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRSharpAc::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
// Start with the previous state if given it. // Start with the previous state if given it.
if (prev != NULL) result = *prev; if (prev != NULL) result = *prev;
result.protocol = decode_type_t::SHARP_AC; result.protocol = decode_type_t::SHARP_AC;

View File

@ -444,7 +444,7 @@ stdAc::swingv_t IRTcl112Ac::toCommonSwingV(const uint8_t setting) {
/// @param[in] prev Ptr to the previous state if required. /// @param[in] prev Ptr to the previous state if required.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRTcl112Ac::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRTcl112Ac::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
// Start with the previous state if given it. // Start with the previous state if given it.
if (prev != NULL) result = *prev; if (prev != NULL) result = *prev;
result.protocol = decode_type_t::TCL112AC; result.protocol = decode_type_t::TCL112AC;

View File

@ -363,7 +363,7 @@ uint16_t IRTechnibelAc::getTimer(void) const {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRTechnibelAc::toCommon(void) const { stdAc::state_t IRTechnibelAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::TECHNIBEL_AC; result.protocol = decode_type_t::TECHNIBEL_AC;
result.power = _.Power; result.power = _.Power;
result.mode = toCommonMode(_.Mode); result.mode = toCommonMode(_.Mode);

View File

@ -294,7 +294,7 @@ stdAc::fanspeed_t IRTecoAc::toCommonFanSpeed(const uint8_t speed) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRTecoAc::toCommon(void) const { stdAc::state_t IRTecoAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::TECO; result.protocol = decode_type_t::TECO;
result.model = -1; // Not supported. result.model = -1; // Not supported.
result.power = _.Power; result.power = _.Power;

View File

@ -6,6 +6,7 @@
// Supports: // Supports:
// Brand: Teknopoint, Model: Allegro SSA-09H A/C // Brand: Teknopoint, Model: Allegro SSA-09H A/C
// Brand: Teknopoint, Model: GZ-055B-E1 remote // Brand: Teknopoint, Model: GZ-055B-E1 remote
// Brand: Teknopoint, Model: GZ01-BEJ0-000 remote
#include "IRrecv.h" #include "IRrecv.h"
#include "IRsend.h" #include "IRsend.h"
@ -73,3 +74,8 @@ bool IRrecv::decodeTeknopoint(decode_results *results, uint16_t offset,
return true; return true;
} }
#endif // DECODE_TEKNOPOINT #endif // DECODE_TEKNOPOINT
// Looking for the IRTeknopoint/IRTeknopointAc class?
// It doesn't exist, it is instead part of the `IRTcl112Ac` class.
// i.e. use `IRTcl112Ac::setModel(tcl_ac_remote_model_t::GZ055BE1);` for
// Teknopoint A/Cs.

View File

@ -409,7 +409,7 @@ stdAc::fanspeed_t IRToshibaAC::toCommonFanSpeed(const uint8_t spd) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRToshibaAC::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRToshibaAC::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
// Start with the previous state if given it. // Start with the previous state if given it.
if (prev != NULL) { if (prev != NULL) {
result = *prev; result = *prev;

View File

@ -339,7 +339,7 @@ stdAc::fanspeed_t IRTranscoldAc::toCommonFanSpeed(const uint8_t speed) {
/// @param[in] prev Ptr to the previous state if required. /// @param[in] prev Ptr to the previous state if required.
/// @return A stdAc::state_t state. /// @return A stdAc::state_t state.
stdAc::state_t IRTranscoldAc::toCommon(const stdAc::state_t *prev) const { stdAc::state_t IRTranscoldAc::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result; stdAc::state_t result{};
// Start with the previous state if given it. // Start with the previous state if given it.
if (prev != NULL) { if (prev != NULL) {
result = *prev; result = *prev;

View File

@ -266,7 +266,7 @@ stdAc::fanspeed_t IRTrotecESP::toCommonFanSpeed(const uint8_t spd) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRTrotecESP::toCommon(void) const { stdAc::state_t IRTrotecESP::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::TROTEC; result.protocol = decode_type_t::TROTEC;
result.power = _.Power; result.power = _.Power;
result.mode = toCommonMode(_.Mode); result.mode = toCommonMode(_.Mode);
@ -601,7 +601,7 @@ stdAc::fanspeed_t IRTrotec3550::toCommonFanSpeed(const uint8_t spd) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRTrotec3550::toCommon(void) const { stdAc::state_t IRTrotec3550::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::TROTEC_3550; result.protocol = decode_type_t::TROTEC_3550;
result.power = _.Power; result.power = _.Power;
result.mode = toCommonMode(_.Mode); result.mode = toCommonMode(_.Mode);

View File

@ -295,7 +295,7 @@ stdAc::fanspeed_t IRTrumaAc::toCommonFanSpeed(const uint8_t spd) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRTrumaAc::toCommon(void) const { stdAc::state_t IRTrumaAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::TRUMA; result.protocol = decode_type_t::TRUMA;
result.model = -1; // Not supported. result.model = -1; // Not supported.

View File

@ -442,7 +442,7 @@ stdAc::fanspeed_t IRVestelAc::toCommonFanSpeed(const uint8_t spd) {
/// Convert the current internal state into its stdAc::state_t equivalent. /// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings. /// @return The stdAc equivalent of the native settings.
stdAc::state_t IRVestelAc::toCommon(void) const { stdAc::state_t IRVestelAc::toCommon(void) const {
stdAc::state_t result; stdAc::state_t result{};
result.protocol = decode_type_t::VESTEL_AC; result.protocol = decode_type_t::VESTEL_AC;
result.model = -1; // Not supported. result.model = -1; // Not supported.
result.power = _.Power; result.power = _.Power;

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