mirror of https://github.com/arendst/Tasmota.git
IRremoteESP8266 upgraded to v2.8.5 (#18610)
* IRremoteESP8266 upgraded to v2.8.5 (from v2.8.4)
* Fix ir panasonic esp8266 (#18013)
* revert part of #16179 for ESP8266
* Revert "revert part of #16179 for ESP8266"
This reverts commit b8e6126407
.
* try to revert #16179 for esp8266
* Build: removed redundand USE_IR_REMOTE_FULL flag
Tasmota32-ir PIO had both FIRMWARE_IR and USE_IR_REMOTE_FULL defined.
The latter is redundand and yielded unnecessary build warns.
See: tasmota_configurations.h
---------
Co-authored-by: Mateusz Bronk <2566147+mbronk@users.noreply.github.com>
Co-authored-by: Barbudor <barbudor@barbudor.net>
This commit is contained in:
parent
6fe1bbd617
commit
faff39ca11
|
@ -7,9 +7,31 @@ on:
|
|||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
Build_Examples:
|
||||
|
||||
Gen_Matrix:
|
||||
outputs:
|
||||
matrix: ${{ steps.files.outputs.matrix }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Generate Matrix of all examples
|
||||
id: files
|
||||
run: |
|
||||
JSONI=$(find . -name platformio.ini -type f | sed 's,/platformio.ini$,,' | xargs -n 1 -I {} echo -e '"{}",')
|
||||
|
||||
# Remove last "," and add closing brackets
|
||||
if [[ $JSONI == *, ]]; then
|
||||
JSONI="${JSONI%?}"
|
||||
fi
|
||||
JSONI=${JSONI//$'\n'}
|
||||
echo $JSONI
|
||||
# Set output
|
||||
echo "::set-output name=matrix::[${JSONI}]"
|
||||
Build_Example:
|
||||
needs: Gen_Matrix
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
project: ${{fromJson(needs.Gen_Matrix.outputs.matrix)}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -24,14 +46,29 @@ jobs:
|
|||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/platformio.ini') }}
|
||||
- name: Cache PlatformIO build
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .pio
|
||||
key: pio-${{ runner.os }}-${{ matrix.project }}
|
||||
restore-keys: |
|
||||
pio-${{ runner.os }}-
|
||||
pio-
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
- name: Install PlatformIO
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade platformio
|
||||
- name: Build all the examples
|
||||
- name: Build example
|
||||
env:
|
||||
PLATFORMIO_BUILD_CACHE_DIR: "../../.pio/buildcache"
|
||||
run: find . -name platformio.ini -type f | sed 's,/platformio.ini$,,' | xargs --verbose -n 1 pio run --jobs 2 --project-dir
|
||||
run: pio run --jobs 2 --project-dir ${{ matrix.project }}
|
||||
|
||||
Build_Examples:
|
||||
needs: Build_Example
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: done
|
||||
run: echo ok
|
||||
|
|
|
@ -37,7 +37,7 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- name: Check all the version numbers match.
|
||||
run: |
|
||||
LIB_VERSION=$(egrep "^#define\s+_IRREMOTEESP8266_VERSION_\s+" src/IRremoteESP8266.h | cut -d\" -f2)
|
||||
LIB_VERSION=$(tools/extract_lib_version.sh)
|
||||
test ${LIB_VERSION} == "$(jq -r .version library.json)"
|
||||
grep -q "^version=${LIB_VERSION}$" library.properties
|
||||
examples-have-platformio_ini:
|
||||
|
|
|
@ -3,21 +3,28 @@ name: Tests
|
|||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
Unit_Tests:
|
||||
|
||||
Tools_Tests:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MAKEFLAGS: "-j 2"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Build tools unit tests
|
||||
run: (cd tools; make all)
|
||||
- name: Run tools unit tests
|
||||
run: (cd tools; make run_tests)
|
||||
|
||||
Unit_Tests:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MAKEFLAGS: "-j 2"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install the Google test suite
|
||||
env:
|
||||
MAKEFLAGS: "-j 2"
|
||||
run: (cd test; make install-googletest)
|
||||
- name: Build and run the library unit tests.
|
||||
env:
|
||||
MAKEFLAGS: "-j 2"
|
||||
- name: Build base unit test
|
||||
run: (cd test; make IRac_test)
|
||||
- name: Build library unit tests
|
||||
run: (cd test; make all)
|
||||
- name: Run library unit tests
|
||||
run: (cd test; make run)
|
||||
- name: Build and run the tools unit tests.
|
||||
env:
|
||||
MAKEFLAGS: "-j 2"
|
||||
run: (cd tools; make all; make run_tests)
|
||||
|
|
72
lib/lib_basic/IRremoteESP8266/IRremoteESP8266/.github/workflows/codeql-analysis.yml
vendored
Normal file
72
lib/lib_basic/IRremoteESP8266/IRremoteESP8266/.github/workflows/codeql-analysis.yml
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '38 1 * * 3'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'python' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
|
@ -40,6 +40,7 @@ tools/*.o
|
|||
tools/*.a
|
||||
tools/gc_decode
|
||||
tools/mode2_decode
|
||||
tools/code_to_raw
|
||||
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
|
@ -51,3 +52,4 @@ tools/mode2_decode
|
|||
|
||||
# Mac extended attributes
|
||||
.DS_Store
|
||||
/.vs
|
||||
|
|
|
@ -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
|
||||
[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.4 Now Available
|
||||
Version 2.8.4 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes.
|
||||
## v2.8.5 Now Available
|
||||
Version 2.8.5 of the library is now [available](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). You can view the [Release Notes](ReleaseNotes.md) for all the significant changes.
|
||||
|
||||
#### Upgrading from pre-v2.0
|
||||
Usage of the library has been slightly changed in v2.0. You will need to change your usage to work with v2.0 and beyond. You can read more about the changes required on our [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
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.
|
||||
|
||||
## v2.8.4 jetzt verfügbar
|
||||
Version 2.8.4 der Bibliothek ist nun [verfügbar](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Die [Versionshinweise](ReleaseNotes.md) enthalten alle wichtigen Neuerungen.
|
||||
## v2.8.5 jetzt verfügbar
|
||||
Version 2.8.5 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
|
||||
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.
|
||||
|
|
|
@ -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
|
||||
[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.4 disponible
|
||||
Version 2.8.4 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants.
|
||||
## v2.8.5 disponible
|
||||
Version 2.8.5 de la libraire est maintenant [disponible](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Vous pouvez voir le [Release Notes](ReleaseNotes.md) pour tous les changements importants.
|
||||
|
||||
#### mise à jour depuis pre-v2.0
|
||||
L'utilisation de la librairie à un peu changer depuis la version in v2.0. Si vous voulez l'utiliser vous devrez changer votre utilisation aussi. Vous pouvez vous renseigner sur les précondition d'utilisation ici : [Upgrade to v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) page.
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
![IRremoteESP8266 Library](./assets/images/banner.svg)
|
||||
|
||||
[![Build-Status](https://github.com/crankyoldgit/IRremoteESP8266/actions/workflows/Build.yml/badge.svg)](../../actions/workflows/Build.yml/badge.svg)
|
||||
[![Code-Lint](https://github.com/crankyoldgit/IRremoteESP8266/actions/workflows/Lint.yml/badge.svg)](../../actions/workflows/Lint.yml)
|
||||
[![Tests](https://github.com/crankyoldgit/IRremoteESP8266/actions/workflows/UnitTests.yml/badge.svg)](../../ctions/workflows/UnitTests.yml)
|
||||
[![Dokumentation](https://github.com/crankyoldgit/IRremoteESP8266/actions/workflows/Documentation.yml/badge.svg)](../../actions/workflows/Documentation.yml)
|
||||
[![arduino-library-badge](https://www.ardu-badge.com/badge/IRremoteESP8266.svg?)](https://www.ardu-badge.com/IRremoteESP8266)
|
||||
[![Arduino-Bibliothek-Abzeichen](https://www.ardu-badge.com/badge/IRremoteESP8266.svg?)](https://www.ardu-badge.com/IRremoteESP8266)
|
||||
[![Git-Lizenz](https://gitlicense.com/badge/crankyoldgit/IRremoteESP8266)](https://gitlicense.com/license/crankyoldgit/IRremoteESP8266)
|
||||
|
||||
Deze library maakt het mogelijk om Infraroodsignalen **te versturen en ontvangen** via het [Arduino framework](https://www.arduino.cc/) met veelgebruikte 940nm IR LEDs en IR ontvang modules. b.v. TSOP{17,22,24,36,38,44,48}* demodulatoren enz.
|
||||
|
||||
## v2.8.5 nu beschikbaar
|
||||
Versie 2.8.5 van de bibliotheek is nu [beschikbaar](https://github.com/crankyoldgit/IRremoteESP8266/releases/latest). Bekijk de [Release Notes](ReleaseNotes.md) voor alle belangrijke veranderingen.
|
||||
|
||||
#### Upgraden vanaf pre-v2.0
|
||||
Het gebruik van de bibliotheek is enigszins gewijzigd in v2.0. Je zult het gebruik moeten aanpassen om te kunnen werken met v2.0 en hoger. Je kunt meer lezen over de vereiste aanpassingen op onze [Upgraden naar v2.0](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Upgrading-to-v2.0) pagina.
|
||||
|
||||
#### Upgraden vanaf pre-v2.5
|
||||
De bibliotheek defineert constanten nu niet meer als `#define`, maar gebruikt
|
||||
[const](https://google.github.io/styleguide/cppguide.html#Constant_Names) met
|
||||
de juiste naamgeving volgens de
|
||||
[C++ style guide](https://google.github.io/styleguide/cppguide.html).
|
||||
Dit kan ertoe leiden dat oude programma's niet compileren.
|
||||
De meest extern gebruikte `#define`s zijn _gealiased_ voor beperkte
|
||||
compatibiliteit voor projecten die de oude stijl gebruiken. In de toekomst zal alleen de
|
||||
nieuwe `kConstantName` stijl worden ondersteund voor nieuwe protocoltoevoegingen.
|
||||
|
||||
In het onwaarschijnlijke geval dat het je code breekt, dan heb je misschien verwezen naar
|
||||
iets wat je waarschijnlijk niet had moeten doen. Gelukkig is het redelijk simpel om de nieuwe naam
|
||||
te bepalen vanaf de oude, b.v. `CONSTANT_NAME` naar `kConstantName`.
|
||||
Gebruik gezond verstand of onderzoek de code van de bibliotheek als dit van toepassing is op jouw code.
|
||||
|
||||
## Ondersteunde Protocollen
|
||||
De details van de ondersteunde protocollen en apparaten staan
|
||||
[hier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/SupportedProtocols.md) vermeld.
|
||||
|
||||
## Probleemoplossing
|
||||
Voordat je een probleem meldt of om hulp vraagt, graag eerst onze [Probleemoplossingsgids](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide) volgen.
|
||||
|
||||
## Veelgestelde Vragen
|
||||
Enkele antwoorden op veel veelgestelde vragen en problemen staan op onze [F.A.Q. wiki pagina](https://github.com/crankyoldgit/IRremoteESP8266/wiki/Frequently-Asked-Questions).
|
||||
|
||||
## Bibliotheek API Documentatie
|
||||
De bibliotheek gebruikt [Doxygen](https://www.doxygen.nl/index.html) om [automatisch documentatie](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) toe te voegen aan de [API](https://en.wikipedia.org/wiki/Application_programming_interface) van de [bibliotheek](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/).
|
||||
Je kunt de documentatie [hier](https://crankyoldgit.github.io/IRremoteESP8266/doxygen/html/) vinden.
|
||||
|
||||
## Installatie
|
||||
##### Officiële versies via de Arduino IDE v1.8+ (Windows & Linux)
|
||||
1. Klik op de _"Schets"_ -> _"Bibliotheek gebruiken"_ -> _"Bibliotheken beheren..."_ menuknoppen.
|
||||
1. Vul `IRremoteESP8266` in bij _"Filter je zoekresultaten..."_ rechtsboven de pop-up.
|
||||
1. Klik op het IRremoteESP8266 resultaat van de zoekopdracht.
|
||||
1. Selecteer de versie die je wilt installeren en klik op _"Installeren"_.
|
||||
|
||||
##### Handmatige installatie voor Windows
|
||||
1. Klik op de _"Clone or Download"_ knop, en kies dan _"[Download ZIP](https://github.com/crankyoldgit/IRremoteESP8266/archive->master.zip)"_.
|
||||
1. Pak de inhoud van de gedownloade zip uit.
|
||||
1. Hernoem de uitgepakte map naar _"IRremoteESP8266"_.
|
||||
1. Verplaats de map naar de bibliotheken map. (voor Windows: `C:\Gebruikers\GEBRUIKERSNAAM\Documenten\Arduino\libraries\`)
|
||||
1. Herstart de Arduino IDE.
|
||||
1. Bekijk de voorbeelden.
|
||||
|
||||
##### Git gebruiken om de bibliotheken te installeren ( Linux )
|
||||
```
|
||||
cd ~/Arduino/libraries
|
||||
git clone https://github.com/crankyoldgit/IRremoteESP8266.git
|
||||
```
|
||||
###### Om de bibliotheken te updaten naar de laatste versie
|
||||
```
|
||||
cd ~/Arduino/libraries/IRremoteESP8266 && git pull
|
||||
```
|
||||
|
||||
## Bijdragen
|
||||
Als je wilt [bijdragen](.github/CONTRIBUTING.md#how-can-i-contribute) aan dit project, hulp is altijd welkom bij:
|
||||
- Het [melden](.github/CONTRIBUTING.md#reporting-bugs) van problemen en foutmeldingen
|
||||
- Ideeën voor verbeteringen
|
||||
- Verbeteringen van de documentatie
|
||||
- [Het aanmaken van issues](.github/CONTRIBUTING.md#reporting-bugs) en [pull requests](.github/CONTRIBUTING.md#pull-requests)
|
||||
- Het delen van deze bibliotheek
|
||||
|
||||
## Bijdragers
|
||||
Bekijk alle bijdragers [hier](.github/Contributors.md)
|
||||
|
||||
## Bibliotheek Geschiedenis
|
||||
Deze bibliotheek was oorspronkelijk gebaseerd op het werk van Ken Shirriff (https://github.com/shirriff/Arduino-IRremote/)
|
||||
|
||||
[Mark Szabo](https://github.com/crankyoldgit/IRremoteESP8266) heeft de IRsend class bijgewerkt om te werken op een ESP8266 en [Sebastien Warin](https://github.com/sebastienwarin/IRremoteESP8266) de ontvang & decodeer class (IRrecv).
|
||||
|
||||
Voor v2.0 is de bibliotheek bijna volledig herschreven met de mogelijkheden van de ESP8266 in het achterhoofd.
|
|
@ -1,5 +1,41 @@
|
|||
# Release Notes
|
||||
|
||||
## _v2.8.5 (20230508)_
|
||||
|
||||
**[Bug Fixes]**
|
||||
- Fix a bug where we never detached the timer interrupt on ESP32s. (#1984 #1983)
|
||||
- Missing argument in use of midea function (#1959 #1958)
|
||||
- IRMQTTServer: Improve HA MQTT climate handling. (#1911)
|
||||
- SEND_SANYO_AC88: Fix poor cut-n-paste error (#1905 #1897)
|
||||
|
||||
**[Features]**
|
||||
- Add support for a 40bit variant of the standard Panasonic protocol (#1977 @1976)
|
||||
- Initial support for York AC protocol (#1889)
|
||||
- IRMQTTServer: SHT-3x Temperature Sensor Support (#1951)
|
||||
- IRMQTTServer: HA multi output discovery (#1947)
|
||||
- IRMQTTServer: extended with new A/C common fields (#1940)
|
||||
- IRMQTTServer: Sync the on state to power from mode for HA (#1946)
|
||||
- Experimental basic support for Carrier 84-bit protocol. (#1945 #1943)
|
||||
- Add support the WowWee 11-Bit RoboRaptor-X protocol. (#1939 #1938)
|
||||
- Added 'sensorTemperature' and 'iFeel' to IRac (common) (#1928)
|
||||
- Added extra 'mid' option for Fan & SwingV to IRac (#1929)
|
||||
- Added "commandType" to IRAc (#1921)
|
||||
- Added support for Argo WREM-3 A/C remote protocol [part1] (#1920)
|
||||
- Added Dutch (nl-NL) translation (#1907)
|
||||
- ARGO: Improve code & add support for decoding 32bit sensor msgs. (#1906 #1859)
|
||||
- Added support for Gorenje cooker hood IR protocol (#1888 #1887)
|
||||
|
||||
**[Misc]**
|
||||
- Add Electrolux YKR-H/531E as a supported device (#1981 #1980)
|
||||
- Update `XMP` status to Stable (#1944)
|
||||
- upgrade to a later version of `googletest` (#1936)
|
||||
- MITSUBISHI128: Added model to supported protocol (#1924)
|
||||
- Added Dutch (nl-NL) README (#1908)
|
||||
- Added GMock to UT Makefile (#1902)
|
||||
- Update HA example config for HA 2022.6+ (#1901 #1900)
|
||||
- Add a `d1_mini_noMDNS` build option to `IRMQTTServer`. (#1985)
|
||||
|
||||
|
||||
## _v2.8.4 (20220918)_
|
||||
|
||||
**[Bug Fixes]**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!--- WARNING: Do NOT edit this file directly.
|
||||
It is generated by './tools/scrape_supported_devices.py'.
|
||||
Last generated: Thu 15 Sep 2022 12:54:42 +0000 --->
|
||||
Last generated: Mon 08 May 2023 07:06:16 +0000 --->
|
||||
# IR Protocols supported by this library
|
||||
|
||||
| Protocol | Brand | Model | A/C Model | Detailed A/C Support |
|
||||
|
@ -9,11 +9,11 @@
|
|||
| [Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Airwell.cpp) | **[Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Airwell.h)** | DLS 21 DCI R410 AW A/C<BR>RC04 remote<BR>RC08W remote | | Yes |
|
||||
| [Aiwa](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Aiwa.cpp) | **Aiwa** | RC-T501 RCU | | - |
|
||||
| [Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.cpp) | **[Amcor](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Amcor.h)** | ADR-853H A/C<BR>TAC-444 remote<BR>TAC-495 remote | | Yes |
|
||||
| [Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.cpp) | **[Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.h)** | Ulisse 13 DCI Mobile Split A/C | | Yes |
|
||||
| [Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.cpp) | **[Argo](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Argo.h)** | Ulisse 13 DCI Mobile Split A/C [WREM2 remote]<BR>Ulisse Eco Mobile Split A/C (Wifi) [WREM3 remote] | SAC_WREM2<BR>SAC_WREM3 | Yes |
|
||||
| [Arris](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Arris.cpp) | **Arris** | 120A V1.0 A18 remote<BR>VIP1113M Set-top box | | - |
|
||||
| [Bosch](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Bosch.cpp) | **[Bosch](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Bosch.h)** | CL3000i-Set 26 E A/C<BR>RG10A(G2S)BGEF remote | | Yes |
|
||||
| [Bose](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Bose.cpp) | **Bose** | Bose TV Speaker | | - |
|
||||
| [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **[Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.h)** | 40GKX0E2006 remote (CARRIER_AC128) | | Yes |
|
||||
| [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **[Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.h)** | 3021203 RR03-S-Remote (CARRIER_AC84)<BR>342WM100CT A/C (CARRIER_AC84)<BR>40GKX0E2006 remote (CARRIER_AC128) | | Yes |
|
||||
| [Carrier](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.cpp) | **[Carrier/Surrey](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Carrier.h)** | 42QG5A55970 remote<BR>53NGK009/012 Inverter<BR>619EGX0090E0 A/C<BR>619EGX0120E0 A/C<BR>619EGX0180E0 A/C<BR>619EGX0220E0 A/C | | Yes |
|
||||
| [ClimaButler](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_ClimaButler.cpp) | **Clima-Butler** | AR-715 remote<BR>RCS-SD43UWI A/C | | - |
|
||||
| [Coolix](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.cpp) | **[Airwell](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Coolix.h)** | RC08B remote | | Yes |
|
||||
|
@ -35,6 +35,7 @@
|
|||
| [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) | **[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) | **[Electrolux](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | YKR-H/531E A/C | | Yes |
|
||||
| [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[Frigidaire](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | FGPC102AB1 A/C | | Yes |
|
||||
| [Electra](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.cpp) | **[Subtropic](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Electra.h)** | SUB-07HN1_18Y A/C<BR>YKR-H/102E remote | | Yes |
|
||||
| [EliteScreens](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_EliteScreens.cpp) | **Elite Screens** | CineTension2 / CineTension3 series<BR>Home2 / Home3 series<BR>Spectrum series<BR>VMAX Plus4 series<BR>VMAX2 / VMAX2 Plus series<BR>ZSP-IR-B / ZSP-IR-W remote | | - |
|
||||
|
@ -46,6 +47,7 @@
|
|||
| [GICable](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GICable.cpp) | **G.I. Cable** | XRC-200 remote | | - |
|
||||
| [GlobalCache](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_GlobalCache.cpp) | **Global Cache** | Control Tower IR DB | | - |
|
||||
| [Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.cpp) | **[Goodweather](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Goodweather.h)** | ZH/JT-03 remote | | Yes |
|
||||
| [Gorenje](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gorenje.cpp) | **Gorenje** | DKF 2600 MWT Cooker Hood | | - |
|
||||
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Amana](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | PBC093G00CC A/C<BR>YX1FF remote | YAW1F<BR>YBOFB<BR>YX1FSF | Yes |
|
||||
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[Cooper & Hunter](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | CH-S09FTXG A/C<BR>YB1F2 remote | YAW1F<BR>YBOFB<BR>YX1FSF | Yes |
|
||||
| [Gree](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.cpp) | **[EKOKAI](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Gree.h)** | A/C | YAW1F<BR>YBOFB<BR>YX1FSF | Yes |
|
||||
|
@ -89,7 +91,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) | **[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 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 |
|
||||
| [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>PAR-FA32MA remote (MITSUBISHI136)<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 |
|
||||
| [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 | | - |
|
||||
|
@ -137,7 +139,9 @@
|
|||
| [Voltas](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Voltas.cpp) | **[Voltas](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Voltas.h)** | 122LZF 4011252 Window A/C | 122LZF | Yes |
|
||||
| [Whirlpool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whirlpool.cpp) | **[Whirlpool](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whirlpool.h)** | DG11J1-04 remote<BR>DG11J1-3A remote<BR>DG11J1-91 remote<BR>SPIS409L A/C<BR>SPIS412L A/C<BR>SPIW409L A/C<BR>SPIW412L A/C<BR>SPIW418L A/C | DG11J13A<BR>DG11J191 | Yes |
|
||||
| [Whynter](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Whynter.cpp) | **Whynter** | ARC-110WD A/C | | - |
|
||||
| [Wowwee](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Wowwee.cpp) | **WowWee** | RoboRapter-X | | - |
|
||||
| [Xmp](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Xmp.cpp) | **Xfinity** | XR11 remote<BR>XR2 remote | | - |
|
||||
| [York](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_York.cpp) | **[York](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_York.h)** | GRYLH2A remote<BR>MHH07P17 A/C | | Yes |
|
||||
| [Zepeal](https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_Zepeal.cpp) | **Zepeal** | DRT-A3311(BG) 5 button remote<BR>DRT-A3311(BG) floor fan | | - |
|
||||
|
||||
|
||||
|
@ -164,6 +168,7 @@
|
|||
- CARRIER_AC128
|
||||
- CARRIER_AC40
|
||||
- CARRIER_AC64
|
||||
- CARRIER_AC84
|
||||
- CLIMABUTLER
|
||||
- COOLIX
|
||||
- COOLIX48
|
||||
|
@ -189,6 +194,7 @@
|
|||
- FUJITSU_AC
|
||||
- GICABLE
|
||||
- GOODWEATHER
|
||||
- GORENJE
|
||||
- GREE
|
||||
- HAIER_AC
|
||||
- HAIER_AC160
|
||||
|
@ -267,5 +273,7 @@
|
|||
- VOLTAS
|
||||
- WHIRLPOOL_AC
|
||||
- WHYNTER
|
||||
- WOWWEE
|
||||
- XMP
|
||||
- YORK
|
||||
- ZEPEAL
|
||||
|
|
|
@ -132,6 +132,8 @@ const uint32_t kMqttReconnectTime = 5000; // Delay(ms) between reconnect tries.
|
|||
#define MQTT_CLIMATE "ac" // Sub-topic for the climate topics.
|
||||
#define MQTT_CLIMATE_CMND "cmnd" // Sub-topic for the climate command topics.
|
||||
#define MQTT_CLIMATE_STAT "stat" // Sub-topic for the climate stat topics.
|
||||
// Sub-topic for the temperature/humidity sensor stat topics.
|
||||
#define MQTT_SENSOR_STAT "sensor"
|
||||
// Enable sending/receiving climate via JSON. `true` cost ~5k of program space.
|
||||
#define MQTT_CLIMATE_JSON false
|
||||
|
||||
|
@ -221,6 +223,25 @@ const uint16_t kMinUnknownSize = 2 * 10;
|
|||
// actual a/c unit.
|
||||
#define REPLAY_DECODED_AC_MESSAGE false
|
||||
|
||||
// ------------------------ SHT-3x Support -------------------------------------
|
||||
// To enable SHT-3x sensor support (such as the Lolin SHT30 Shield), connected
|
||||
// to GPIOs 4 and 5 (D2 and D1), do the following:
|
||||
// - uncomment the line in platformio.ini to enable the SHT-3x library
|
||||
// - uncomment the following #define line
|
||||
// #define SHT3X_SUPPORT true
|
||||
|
||||
// Default address for SHT-3x sensor.
|
||||
#define SHT3X_I2C_ADDRESS 0x44
|
||||
// Requires MQTT_DISCOVERY_ENABLE to be true as well.
|
||||
// If set, will send HA MQTT Discovery messages for the SHT-3x sensor.
|
||||
#define SHT3X_MQTT_DISCOVERY_ENABLE true
|
||||
// I2C SDA pin for SHT-3x sensor (D2).
|
||||
#define SHT3X_I2C_SDA 4
|
||||
// I2C SCL pin for SHT-3x sensor (D1).
|
||||
#define SHT3X_I2C_SCL 5
|
||||
// Check frequency for SHT-3x sensor (in seconds).
|
||||
#define SHT3X_CHECK_FREQ 60
|
||||
|
||||
// ------------------------ Advanced Usage Only --------------------------------
|
||||
|
||||
// Reports the input voltage to the ESP chip. **NOT** the input voltage
|
||||
|
@ -238,6 +259,7 @@ const uint16_t kMinUnknownSize = 2 * 10;
|
|||
#define KEY_POWER "power"
|
||||
#define KEY_MODE "mode"
|
||||
#define KEY_TEMP "temp"
|
||||
#define KEY_HUMIDITY "humidity"
|
||||
#define KEY_FANSPEED "fanspeed"
|
||||
#define KEY_SWINGV "swingv"
|
||||
#define KEY_SWINGH "swingh"
|
||||
|
@ -253,6 +275,9 @@ const uint16_t kMinUnknownSize = 2 * 10;
|
|||
#define KEY_JSON "json"
|
||||
#define KEY_RESEND "resend"
|
||||
#define KEY_VCC "vcc"
|
||||
#define KEY_COMMAND "command"
|
||||
#define KEY_SENSORTEMP "sensortemp"
|
||||
#define KEY_IFEEL "ifeel"
|
||||
|
||||
// HTML arguments we will parse for IR code information.
|
||||
#define KEY_TYPE "type" // KEY_PROTOCOL is also checked too.
|
||||
|
@ -260,11 +285,17 @@ const uint16_t kMinUnknownSize = 2 * 10;
|
|||
#define KEY_BITS "bits"
|
||||
#define KEY_REPEAT "repeats"
|
||||
#define KEY_CHANNEL "channel" // Which IR TX channel to send on.
|
||||
#define KEY_SENSORTEMP_DISABLED "sensortemp_disabled" // For HTML form only,
|
||||
// not sent via MQTT
|
||||
// nor JSON
|
||||
|
||||
// GPIO html/config keys
|
||||
#define KEY_TX_GPIO "tx"
|
||||
#define KEY_RX_GPIO "rx"
|
||||
|
||||
// Miscellaneous constants
|
||||
#define TOGGLE_JS_FN_NAME "ToggleInputBasedOnCheckbox"
|
||||
|
||||
// Text for Last Will & Testament status messages.
|
||||
const char* const kLwtOnline = "Online";
|
||||
const char* const kLwtOffline = "Offline";
|
||||
|
@ -290,7 +321,7 @@ const uint16_t kJsonAcStateMaxSize = 1024; // Bytes
|
|||
// ----------------- End of User Configuration Section -------------------------
|
||||
|
||||
// Constants
|
||||
#define _MY_VERSION_ "v1.7.0"
|
||||
#define _MY_VERSION_ "v1.8.2"
|
||||
|
||||
const uint8_t kRebootTime = 15; // Seconds
|
||||
const uint8_t kQuickDisplayTime = 2; // Seconds
|
||||
|
@ -358,7 +389,8 @@ static const char kClimateTopics[] PROGMEM =
|
|||
"(" KEY_PROTOCOL "|" KEY_MODEL "|" KEY_POWER "|" KEY_MODE "|" KEY_TEMP "|"
|
||||
KEY_FANSPEED "|" KEY_SWINGV "|" KEY_SWINGH "|" KEY_QUIET "|"
|
||||
KEY_TURBO "|" KEY_LIGHT "|" KEY_BEEP "|" KEY_ECONO "|" KEY_SLEEP "|"
|
||||
KEY_FILTER "|" KEY_CLEAN "|" KEY_CELSIUS "|" KEY_RESEND
|
||||
KEY_FILTER "|" KEY_CLEAN "|" KEY_CELSIUS "|" KEY_RESEND "|" KEY_COMMAND "|"
|
||||
"|" KEY_SENSORTEMP "|" KEY_IFEEL
|
||||
#if MQTT_CLIMATE_JSON
|
||||
"|" KEY_JSON
|
||||
#endif // MQTT_CLIMATE_JSON
|
||||
|
@ -367,6 +399,7 @@ static const char* const kMqttTopics[] = {
|
|||
KEY_PROTOCOL, KEY_MODEL, KEY_POWER, KEY_MODE, KEY_TEMP, KEY_FANSPEED,
|
||||
KEY_SWINGV, KEY_SWINGH, KEY_QUIET, KEY_TURBO, KEY_LIGHT, KEY_BEEP,
|
||||
KEY_ECONO, KEY_SLEEP, KEY_FILTER, KEY_CLEAN, KEY_CELSIUS, KEY_RESEND,
|
||||
KEY_COMMAND, KEY_SENSORTEMP, KEY_IFEEL
|
||||
KEY_JSON}; // KEY_JSON needs to be the last one.
|
||||
|
||||
|
||||
|
@ -410,7 +443,8 @@ int8_t getDefaultTxGpio(void);
|
|||
String genStatTopic(const uint16_t channel = 0);
|
||||
String listOfTxGpios(void);
|
||||
bool hasUnsafeHTMLChars(String input);
|
||||
String htmlHeader(const String title, const String h1_text = "");
|
||||
String htmlHeader(const String title, const String h1_text = "",
|
||||
const String headScriptsJS = "");
|
||||
String htmlEnd(void);
|
||||
String htmlButton(const String url, const String button,
|
||||
const String text = "");
|
||||
|
@ -418,9 +452,13 @@ String htmlMenu(void);
|
|||
void handleRoot(void);
|
||||
String addJsReloadUrl(const String url, const uint16_t timeout_s,
|
||||
const bool notify);
|
||||
String getJsToggleCheckbox(const String functionName = TOGGLE_JS_FN_NAME);
|
||||
void handleExamples(void);
|
||||
String htmlOptionItem(const String value, const String text, bool selected);
|
||||
String htmlSelectBool(const String name, const bool def);
|
||||
String htmlDisableCheckbox(const String name, const String targetControlId,
|
||||
const bool checked,
|
||||
const String toggleJsFnName = TOGGLE_JS_FN_NAME);
|
||||
String htmlSelectClimateProtocol(const String name, const decode_type_t def);
|
||||
String htmlSelectAcStateProtocol(const String name, const decode_type_t def,
|
||||
const bool simple);
|
||||
|
@ -449,6 +487,9 @@ bool parseStringAndSendPronto(IRsend *irsend, const String str,
|
|||
#if SEND_RAW
|
||||
bool parseStringAndSendRaw(IRsend *irsend, const String str);
|
||||
#endif // SEND_RAW
|
||||
#if SHT3X_SUPPORT
|
||||
void sendMQTTDiscoverySensor(const char *topic, String type);
|
||||
#endif // SH3X_SUPPORT
|
||||
void handleIr(void);
|
||||
void handleNotFound(void);
|
||||
void setup_wifi(void);
|
||||
|
|
|
@ -231,6 +231,49 @@
|
|||
*
|
||||
* In HA's configuration.yaml, add:
|
||||
*
|
||||
* #### New format (Post Home Assistant 2022.6 release)
|
||||
*
|
||||
* mqtt:
|
||||
* climate:
|
||||
* - name: Living Room Aircon
|
||||
* modes:
|
||||
* - "off"
|
||||
* - "auto"
|
||||
* - "cool"
|
||||
* - "heat"
|
||||
* - "dry"
|
||||
* - "fan_only"
|
||||
* fan_modes:
|
||||
* - "Auto"
|
||||
* - "Min"
|
||||
* - "Low"
|
||||
* - "Medium"
|
||||
* - "High"
|
||||
* - "Max"
|
||||
* swing_modes:
|
||||
* - "Off"
|
||||
* - "Auto"
|
||||
* - "Highest"
|
||||
* - "High"
|
||||
* - "Middle"
|
||||
* - "Low"
|
||||
* - "Lowest"
|
||||
* power_command_topic: "ir_server/ac/cmnd/power"
|
||||
* mode_command_topic: "ir_server/ac/cmnd/mode"
|
||||
* mode_state_topic: "ir_server/ac/stat/mode"
|
||||
* temperature_command_topic: "ir_server/ac/cmnd/temp"
|
||||
* temperature_state_topic: "ir_server/ac/stat/temp"
|
||||
* fan_mode_command_topic: "ir_server/ac/cmnd/fanspeed"
|
||||
* fan_mode_state_topic: "ir_server/ac/stat/fanspeed"
|
||||
* swing_mode_command_topic: "ir_server/ac/cmnd/swingv"
|
||||
* swing_mode_state_topic: "ir_server/ac/stat/swingv"
|
||||
* min_temp: 16
|
||||
* max_temp: 32
|
||||
* temp_step: 1
|
||||
* retain: false
|
||||
*
|
||||
* #### Old format (Pre Home Assistant 2022.6 release)
|
||||
*
|
||||
* climate:
|
||||
* - platform: mqtt
|
||||
* name: Living Room Aircon
|
||||
|
@ -256,8 +299,7 @@
|
|||
* - "Middle"
|
||||
* - "Low"
|
||||
* - "Lowest"
|
||||
* # `power_command_topic` is probably not needed for most HA configurations
|
||||
* # power_command_topic: "ir_server/ac/cmnd/power"
|
||||
* power_command_topic: "ir_server/ac/cmnd/power"
|
||||
* mode_command_topic: "ir_server/ac/cmnd/mode"
|
||||
* mode_state_topic: "ir_server/ac/stat/mode"
|
||||
* temperature_command_topic: "ir_server/ac/cmnd/temp"
|
||||
|
@ -377,6 +419,10 @@ using irutils::msToString;
|
|||
ADC_MODE(ADC_VCC);
|
||||
#endif // REPORT_VCC
|
||||
|
||||
#ifdef SHT3X_SUPPORT
|
||||
#include <WEMOS_SHT3X.h>
|
||||
#endif
|
||||
|
||||
// Globals
|
||||
uint8_t _sanity = 0;
|
||||
#if defined(ESP8266)
|
||||
|
@ -453,9 +499,15 @@ String MqttClimateCmnd; // Sub-topic for the climate command topics.
|
|||
#if MQTT_DISCOVERY_ENABLE
|
||||
String MqttDiscovery;
|
||||
String MqttUniqueId;
|
||||
#if SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
String MqttDiscoverySensor;
|
||||
#endif // SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
#endif // MQTT_DISCOVERY_ENABLE
|
||||
String MqttHAName;
|
||||
String MqttClientId;
|
||||
#if SHT3X_SUPPORT
|
||||
String MqttSensorStat;
|
||||
#endif // SHT3X_SUPPORT
|
||||
|
||||
// Primative lock file for gating MQTT state broadcasts.
|
||||
bool lockMqttBroadcast = true;
|
||||
|
@ -495,6 +547,11 @@ bool isSerialGpioUsedByIr(void) {
|
|||
return false; // Not in use as far as we can tell.
|
||||
}
|
||||
|
||||
#if SHT3X_SUPPORT
|
||||
SHT3X TemperatureSensor(SHT3X_I2C_ADDRESS);
|
||||
TimerMs statSensorReadTime = TimerMs();
|
||||
#endif // SHT3X_SUPPORT
|
||||
|
||||
// Debug messages get sent to the serial port.
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
@ -905,7 +962,7 @@ void handleExamples(void) {
|
|||
#endif // EXAMPLES_ENABLE
|
||||
|
||||
String htmlSelectBool(const String name, const bool def) {
|
||||
String html = F("<select name='") + name + F("'>");
|
||||
String html = String(F("<select name='")) + name + F("'>");
|
||||
for (uint16_t i = 0; i < 2; i++)
|
||||
html += htmlOptionItem(IRac::boolToString(i), IRac::boolToString(i),
|
||||
i == def);
|
||||
|
@ -913,8 +970,20 @@ String htmlSelectBool(const String name, const bool def) {
|
|||
return html;
|
||||
}
|
||||
|
||||
String htmlDisableCheckbox(const String name, const String targetControlId,
|
||||
const bool checked, const String toggleJsFnName) {
|
||||
String html = String(F("<input type='checkbox' name='")) + name + F("' id='")
|
||||
+ name + F("' onclick=\"") + toggleJsFnName + F("(this, '") +
|
||||
targetControlId + F("')\"");
|
||||
if (checked) {
|
||||
html += F(" checked");
|
||||
}
|
||||
html += "/><label for='" + name + F("'>Disabled</label>");
|
||||
return html;
|
||||
}
|
||||
|
||||
String htmlSelectClimateProtocol(const String name, const decode_type_t def) {
|
||||
String html = F("<select name='") + name + F("'>");
|
||||
String html = String(F("<select name='")) + name + F("'>");
|
||||
for (uint8_t i = 1; i <= decode_type_t::kLastDecodeType; i++) {
|
||||
if (IRac::isProtocolSupported((decode_type_t)i)) {
|
||||
html += htmlOptionItem(String(i), typeToString((decode_type_t)i),
|
||||
|
@ -926,7 +995,7 @@ String htmlSelectClimateProtocol(const String name, const decode_type_t def) {
|
|||
}
|
||||
|
||||
String htmlSelectModel(const String name, const int16_t def) {
|
||||
String html = F("<select name='") + name + F("'>");
|
||||
String html = String(F("<select name='")) + name + F("'>");
|
||||
for (int16_t i = -1; i <= 6; i++) {
|
||||
String num = String(i);
|
||||
String text;
|
||||
|
@ -942,9 +1011,21 @@ String htmlSelectModel(const String name, const int16_t def) {
|
|||
return html;
|
||||
}
|
||||
|
||||
String htmlSelectCommandType(const String name, const stdAc::ac_command_t def) {
|
||||
String html = String(F("<select name='")) + name + F("'>");
|
||||
for (uint8_t i = 0;
|
||||
i <= (int8_t)stdAc::ac_command_t::kLastAcCommandEnum;
|
||||
i++) {
|
||||
String mode = IRac::commandTypeToString((stdAc::ac_command_t)i);
|
||||
html += htmlOptionItem(mode, mode, (stdAc::ac_command_t)i == def);
|
||||
}
|
||||
html += F("</select>");
|
||||
return html;
|
||||
}
|
||||
|
||||
String htmlSelectUint(const String name, const uint16_t max,
|
||||
const uint16_t def) {
|
||||
String html = F("<select name='") + name + F("'>");
|
||||
String html = String(F("<select name='")) + name + F("'>");
|
||||
for (uint16_t i = 0; i < max; i++) {
|
||||
String num = String(i);
|
||||
html += htmlOptionItem(num, num, i == def);
|
||||
|
@ -955,7 +1036,7 @@ String htmlSelectUint(const String name, const uint16_t max,
|
|||
|
||||
String htmlSelectGpio(const String name, const int16_t def,
|
||||
const int8_t list[], const int16_t length) {
|
||||
String html = F(": <select name='") + name + F("'>");
|
||||
String html = String(F(": <select name='")) + name + F("'>");
|
||||
for (int16_t i = 0; i < length; i++) {
|
||||
String num = String(list[i]);
|
||||
html += htmlOptionItem(num, list[i] == kGpioUnused ? F("Unused") : num,
|
||||
|
@ -967,7 +1048,7 @@ String htmlSelectGpio(const String name, const int16_t def,
|
|||
}
|
||||
|
||||
String htmlSelectMode(const String name, const stdAc::opmode_t def) {
|
||||
String html = F("<select name='") + name + F("'>");
|
||||
String html = String(F("<select name='")) + name + F("'>");
|
||||
for (int8_t i = -1; i <= (int8_t)stdAc::opmode_t::kLastOpmodeEnum; i++) {
|
||||
String mode = IRac::opmodeToString((stdAc::opmode_t)i);
|
||||
html += htmlOptionItem(mode, mode, (stdAc::opmode_t)i == def);
|
||||
|
@ -977,7 +1058,7 @@ String htmlSelectMode(const String name, const stdAc::opmode_t def) {
|
|||
}
|
||||
|
||||
String htmlSelectFanspeed(const String name, const stdAc::fanspeed_t def) {
|
||||
String html = F("<select name='") + name + F("'>");
|
||||
String html = String(F("<select name='")) + name + F("'>");
|
||||
for (int8_t i = 0; i <= (int8_t)stdAc::fanspeed_t::kLastFanspeedEnum; i++) {
|
||||
String speed = IRac::fanspeedToString((stdAc::fanspeed_t)i);
|
||||
html += htmlOptionItem(speed, speed, (stdAc::fanspeed_t)i == def);
|
||||
|
@ -987,7 +1068,7 @@ String htmlSelectFanspeed(const String name, const stdAc::fanspeed_t def) {
|
|||
}
|
||||
|
||||
String htmlSelectSwingv(const String name, const stdAc::swingv_t def) {
|
||||
String html = F("<select name='") + name + F("'>");
|
||||
String html = String(F("<select name='")) + name + F("'>");
|
||||
for (int8_t i = -1; i <= (int8_t)stdAc::swingv_t::kLastSwingvEnum; i++) {
|
||||
String swing = IRac::swingvToString((stdAc::swingv_t)i);
|
||||
html += htmlOptionItem(swing, swing, (stdAc::swingv_t)i == def);
|
||||
|
@ -997,7 +1078,7 @@ String htmlSelectSwingv(const String name, const stdAc::swingv_t def) {
|
|||
}
|
||||
|
||||
String htmlSelectSwingh(const String name, const stdAc::swingh_t def) {
|
||||
String html = F("<select name='") + name + F("'>");
|
||||
String html = String(F("<select name='")) + name + F("'>");
|
||||
for (int8_t i = -1; i <= (int8_t)stdAc::swingh_t::kLastSwinghEnum; i++) {
|
||||
String swing = IRac::swinghToString((stdAc::swingh_t)i);
|
||||
html += htmlOptionItem(swing, swing, (stdAc::swingh_t)i == def);
|
||||
|
@ -1006,14 +1087,20 @@ String htmlSelectSwingh(const String name, const stdAc::swingh_t def) {
|
|||
return html;
|
||||
}
|
||||
|
||||
String htmlHeader(const String title, const String h1_text) {
|
||||
String htmlHeader(const String title, const String h1_text,
|
||||
const String headScriptsJS) {
|
||||
String html = F("<html><head><title>");
|
||||
html += title;
|
||||
html += F("</title><meta http-equiv=\"Content-Type\" "
|
||||
"content=\"text/html;charset=utf-8\">"
|
||||
"<meta name=\"viewport\" content=\"width=device-width,"
|
||||
"initial-scale=1.0,minimum-scale=1.0,maximum-scale=5.0\">"
|
||||
"</head><body><center><h1>");
|
||||
"initial-scale=1.0,minimum-scale=1.0,maximum-scale=5.0\">");
|
||||
if (headScriptsJS.length()) {
|
||||
html += F("<script type=\"text/javascript\">\n");
|
||||
html += headScriptsJS;
|
||||
html += F("</script>\n");
|
||||
}
|
||||
html += F("</head><body><center><h1>");
|
||||
if (h1_text.length())
|
||||
html += h1_text;
|
||||
else
|
||||
|
@ -1036,15 +1123,26 @@ String htmlButton(const String url, const String button, const String text) {
|
|||
return html;
|
||||
}
|
||||
|
||||
String getJsToggleCheckbox(const String functionName) {
|
||||
const String javascript =
|
||||
String(F(" function ")) + functionName + F("(checkbox, targetInputId) {\n"
|
||||
" var targetControl = document.getElementById(targetInputId);\n"
|
||||
" targetControl.disabled = checkbox.checked;\n"
|
||||
" if (!targetControl.disabled) { targetControl.focus(); }\n"
|
||||
" }\n");
|
||||
return javascript;
|
||||
}
|
||||
|
||||
// Admin web page
|
||||
void handleAirCon(void) {
|
||||
String html = htmlHeader(F("Air Conditioner Control"));
|
||||
String html = htmlHeader(F("Air Conditioner Control"), "",
|
||||
getJsToggleCheckbox());
|
||||
html += htmlMenu();
|
||||
if (kNrOfIrTxGpios > 1) {
|
||||
html += F("<form method='POST' action='/aircon/set'"
|
||||
html += String(F("<form method='POST' action='/aircon/set'"
|
||||
" enctype='multipart/form-data'>"
|
||||
"<table>"
|
||||
"<tr><td><b>Climate #</b></td><td>") +
|
||||
"<tr><td><b>Climate #</b></td><td>")) +
|
||||
htmlSelectUint(KEY_CHANNEL, kNrOfIrTxGpios, chan) +
|
||||
F("<input type='submit' value='Change'>"
|
||||
"</td></tr>"
|
||||
|
@ -1053,11 +1151,12 @@ void handleAirCon(void) {
|
|||
"<hr>");
|
||||
}
|
||||
if (climate[chan] != NULL) {
|
||||
html += F("<h3>Current Settings</h3>"
|
||||
bool noSensorTemp = (climate[chan]->next.sensorTemperature == kNoTempValue);
|
||||
html += String(F("<h3>Current Settings</h3>"
|
||||
"<form method='POST' action='/aircon/set'"
|
||||
" enctype='multipart/form-data'>"
|
||||
"<input type='hidden' name='" KEY_CHANNEL "' value='") + String(chan) +
|
||||
F("'>") +
|
||||
"<input type='hidden' name='" KEY_CHANNEL "' value='")) + String(chan)
|
||||
+ F("'>") +
|
||||
F("<table style='width:33%'>"
|
||||
"<tr><td>" D_STR_PROTOCOL "</td><td>") +
|
||||
htmlSelectClimateProtocol(KEY_PROTOCOL,
|
||||
|
@ -1066,6 +1165,9 @@ void handleAirCon(void) {
|
|||
"<tr><td>" D_STR_MODEL "</td><td>") +
|
||||
htmlSelectModel(KEY_MODEL, climate[chan]->next.model) +
|
||||
F("</td></tr>"
|
||||
"<tr><td>" D_STR_COMMAND "</td><td>") +
|
||||
htmlSelectCommandType(KEY_COMMAND, climate[chan]->next.command) +
|
||||
F("</td></tr>"
|
||||
"<tr><td>" D_STR_POWER "</td><td>") +
|
||||
htmlSelectBool(KEY_POWER, climate[chan]->next.power) +
|
||||
F("</td></tr>"
|
||||
|
@ -1084,6 +1186,16 @@ void handleAirCon(void) {
|
|||
(!climate[chan]->next.celsius ? " selected='selected'" : "") +
|
||||
F(">F</option>"
|
||||
"</select></td></tr>"
|
||||
"<tr><td>" D_STR_SENSORTEMP "</td><td>"
|
||||
"<input type='number' name='" KEY_SENSORTEMP "' "
|
||||
"id='" KEY_SENSORTEMP "' min='16' max='90' step='0.5' value='") +
|
||||
(noSensorTemp ? String(climate[chan]->next.degrees, 1) :
|
||||
String(climate[chan]->next.sensorTemperature, 1)) +
|
||||
F("'") +
|
||||
(noSensorTemp ? " disabled" : "") + F(">") +
|
||||
htmlDisableCheckbox(KEY_SENSORTEMP_DISABLED, KEY_SENSORTEMP,
|
||||
noSensorTemp) +
|
||||
F("</td></tr>"
|
||||
"<tr><td>" D_STR_FAN "</td><td>") +
|
||||
htmlSelectFanspeed(KEY_FANSPEED, climate[chan]->next.fanspeed) +
|
||||
F("</td></tr>"
|
||||
|
@ -1096,6 +1208,9 @@ void handleAirCon(void) {
|
|||
"<tr><td>" D_STR_QUIET "</td><td>") +
|
||||
htmlSelectBool(KEY_QUIET, climate[chan]->next.quiet) +
|
||||
F("</td></tr>"
|
||||
"<tr><td>" D_STR_IFEEL "</td><td>") +
|
||||
htmlSelectBool(KEY_IFEEL, climate[chan]->next.iFeel) +
|
||||
F("</td></tr>"
|
||||
"<tr><td>" D_STR_TURBO "</td><td>") +
|
||||
htmlSelectBool(KEY_TURBO, climate[chan]->next.turbo) +
|
||||
F("</td></tr>"
|
||||
|
@ -1190,7 +1305,13 @@ void handleAdmin(void) {
|
|||
#if MQTT_DISCOVERY_ENABLE
|
||||
html += htmlButton(
|
||||
kUrlSendDiscovery, F("Send MQTT Discovery"),
|
||||
F("Send a Climate MQTT discovery message to Home Assistant.<br><br>"));
|
||||
#if SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
F("Send a Climate and Sensor MQTT"
|
||||
#else
|
||||
F("Send a Climate MQTT"
|
||||
#endif // SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
" discovery message to Home Assistant.<br><br>"));
|
||||
|
||||
#endif // MQTT_DISCOVERY_ENABLE
|
||||
#if MQTT_CLEAR_ENABLE
|
||||
html += htmlButton(
|
||||
|
@ -1244,8 +1365,8 @@ void handleInfo(void) {
|
|||
String html = htmlHeader(F("IR MQTT server info"));
|
||||
html += htmlMenu();
|
||||
html +=
|
||||
F("<h3>General</h3>"
|
||||
"<p>Hostname: ") + String(Hostname) + F("<br>"
|
||||
String(F("<h3>General</h3>"
|
||||
"<p>Hostname: ")) + String(Hostname) + F("<br>"
|
||||
"IP address: ") + WiFi.localIP().toString() + F("<br>"
|
||||
"MAC address: ") + WiFi.macAddress() + F("<br>"
|
||||
"Booted: ") + timeSince(1) + F("<br>") +
|
||||
|
@ -1392,6 +1513,10 @@ bool clearMqttSavedStates(const String topic_base) {
|
|||
#if MQTT_DISCOVERY_ENABLE
|
||||
// Clear the HA climate discovery message.
|
||||
success &= mqtt_client.publish(MqttDiscovery.c_str(), "", true);
|
||||
#if SHT3X_SUPPORT && MQTT_DISCOVERY_ENABLE
|
||||
// Clear the HA sensor discovery message.
|
||||
success &= mqtt_client.publish(MqttDiscoverySensor.c_str(), "", true);
|
||||
#endif // SHT3X_SUPPORT && MQTT_DISCOVERY_ENABLE
|
||||
#endif // MQTT_DISCOVERY_ENABLE
|
||||
for (size_t channel = 0;
|
||||
channel <= kNrOfIrTxGpios;
|
||||
|
@ -2106,13 +2231,20 @@ void init_vars(void) {
|
|||
MqttClimateCmnd = MqttClimate + '/' + MQTT_CLIMATE_CMND + '/';
|
||||
// Sub-topic for the climate stat topics.
|
||||
#if MQTT_DISCOVERY_ENABLE
|
||||
MqttDiscovery = "homeassistant/climate/" + String(Hostname) + "/config";
|
||||
MqttDiscovery = "homeassistant/climate/" + String(Hostname);
|
||||
#if SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
MqttDiscoverySensor = "homeassistant/sensor/" + String(Hostname);
|
||||
#endif // SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
MqttUniqueId = WiFi.macAddress();
|
||||
MqttUniqueId.replace(":", "");
|
||||
#endif // MQTT_DISCOVERY_ENABLE
|
||||
MqttHAName = String(Hostname) + "_aircon";
|
||||
// Create a unique MQTT client id.
|
||||
MqttClientId = String(Hostname) + String(kChipId, HEX);
|
||||
#if SHT3X_SUPPORT
|
||||
// Sub-topic for the climate stat topics.
|
||||
MqttSensorStat = String(MqttPrefix) + '/' + MQTT_SENSOR_STAT + '/';
|
||||
#endif // SHT3X_SUPPORT
|
||||
#endif // MQTT_ENABLE
|
||||
}
|
||||
|
||||
|
@ -2418,6 +2550,9 @@ void handleSendMqttDiscovery(void) {
|
|||
htmlMenu() +
|
||||
F("<p>The Home Assistant MQTT Discovery message is being sent to topic: ")
|
||||
+ MqttDiscovery +
|
||||
#if SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
F(" and ") + MqttDiscoverySensor +
|
||||
#endif // SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
F(". It will show up in Home Assistant in a few seconds."
|
||||
"</p>"
|
||||
"<h3>Warning!</h3>"
|
||||
|
@ -2425,7 +2560,15 @@ void handleSendMqttDiscovery(void) {
|
|||
" is sent.</p>") +
|
||||
addJsReloadUrl(kUrlRoot, kRebootTime, true) +
|
||||
htmlEnd());
|
||||
sendMQTTDiscovery(MqttDiscovery.c_str());
|
||||
for (uint16_t i = 0; i < kNrOfIrTxGpios; i++) {
|
||||
String channel_id = "";
|
||||
if (i > 0) channel_id = "_" + String(i);
|
||||
sendMQTTDiscovery(MqttDiscovery.c_str(), channel_id);
|
||||
}
|
||||
#if SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
sendMQTTDiscoverySensor(MqttDiscoverySensor.c_str(), KEY_TEMP);
|
||||
sendMQTTDiscoverySensor(MqttDiscoverySensor.c_str(), KEY_HUMIDITY);
|
||||
#endif // SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
}
|
||||
#endif // MQTT_DISCOVERY_ENABLE
|
||||
|
||||
|
@ -2598,12 +2741,13 @@ void mqttCallback(char* topic, byte* payload, unsigned int length) {
|
|||
}
|
||||
|
||||
#if MQTT_DISCOVERY_ENABLE
|
||||
void sendMQTTDiscovery(const char *topic) {
|
||||
void sendMQTTDiscovery(const char *topic, String channel_id) {
|
||||
String pub_topic = String(topic) + channel_id + F("/config");
|
||||
if (mqtt_client.publish(
|
||||
topic, String(
|
||||
pub_topic.c_str(), String(
|
||||
F("{"
|
||||
"\"~\":\"") + MqttClimate + F("\","
|
||||
"\"name\":\"") + MqttHAName + F("\","
|
||||
"\"~\":\"") + MqttClimate + channel_id + F("\","
|
||||
"\"name\":\"") + MqttHAName + channel_id + F("\","
|
||||
#if (!MQTT_CLIMATE_HA_MODE)
|
||||
// Typically we don't need or use the power command topic if we are using
|
||||
// our Home Assistant Climate compatiblity mode. It causes odd behaviour
|
||||
|
@ -2629,9 +2773,12 @@ void sendMQTTDiscovery(const char *topic) {
|
|||
"\"swing_modes\":[\"" D_STR_OFF "\",\"" D_STR_AUTO "\",\"" D_STR_HIGHEST
|
||||
"\",\"" D_STR_HIGH "\",\"" D_STR_MIDDLE "\",\""
|
||||
D_STR_LOW "\",\"" D_STR_LOWEST "\"],"
|
||||
"\"uniq_id\":\"") + MqttUniqueId + F("\","
|
||||
#if SHT3X_SUPPORT
|
||||
"\"curr_temp_t\":\"") + MqttSensorStat + F(KEY_TEMP "\","
|
||||
#endif // SHT3X_SUPPORT
|
||||
"\"uniq_id\":\"") + MqttUniqueId + channel_id + F("\","
|
||||
"\"device\":{"
|
||||
"\"identifiers\":[\"") + MqttUniqueId + F("\"],"
|
||||
"\"identifiers\":[\"") + MqttUniqueId + channel_id + F("\"],"
|
||||
"\"connections\":[[\"mac\",\"") + WiFi.macAddress() + F("\"]],"
|
||||
"\"manufacturer\":\"IRremoteESP8266\","
|
||||
"\"model\":\"IRMQTTServer\","
|
||||
|
@ -2647,6 +2794,47 @@ void sendMQTTDiscovery(const char *topic) {
|
|||
mqttLog(PSTR("MQTT climate discovery FAILED to send."));
|
||||
}
|
||||
}
|
||||
|
||||
#if SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
// Send the MQTT Discovery data for the SHT3X sensor.
|
||||
// type must be a String of either KEY_TEMP or KEY_HUMIDITY.
|
||||
void sendMQTTDiscoverySensor(const char *topic, String type) {
|
||||
String pub_topic = String(topic) + F("_") + type + F("/config");
|
||||
String uom = "%";
|
||||
String ha_class = type;
|
||||
// XXX Update units of measure for temperature.
|
||||
if (type == KEY_TEMP) {
|
||||
uom = "°C";
|
||||
ha_class = "temperature";
|
||||
}
|
||||
if (mqtt_client.publish(
|
||||
pub_topic.c_str(), String(
|
||||
F("{"
|
||||
"\"name\":\"") + MqttHAName + "_" + type + F("\","
|
||||
|
||||
"\"stat_t\":\"") + MqttSensorStat + type + F("\","
|
||||
"\"dev_cla\":\"") + ha_class + F("\","
|
||||
"\"unit_of_meas\":\"") + uom + F("\","
|
||||
|
||||
"\"uniq_id\":\"") + MqttUniqueId + type + F("\","
|
||||
"\"device\":{"
|
||||
"\"identifiers\":[\"") + MqttUniqueId + type + F("\"],"
|
||||
"\"connections\":[[\"mac\",\"") + WiFi.macAddress() + F("\"]],"
|
||||
"\"manufacturer\":\"IRremoteESP8266\","
|
||||
"\"model\":\"IRMQTTServer\","
|
||||
"\"name\":\"") + Hostname + F("\","
|
||||
"\"sw_version\":\"" _MY_VERSION_ "\""
|
||||
"}"
|
||||
"}")).c_str(), true)) {
|
||||
mqttLog(PSTR("MQTT sensor discovery successful sent."));
|
||||
hasDiscoveryBeenSent = true;
|
||||
lastDiscovery.reset();
|
||||
mqttSentCounter++;
|
||||
} else {
|
||||
mqttLog(PSTR("MQTT sensor discovery FAILED to send."));
|
||||
}
|
||||
}
|
||||
#endif // SHT3X_SUPPORT && SHT3X_MQTT_DISCOVERY_ENABLE
|
||||
#endif // MQTT_DISCOVERY_ENABLE
|
||||
#endif // MQTT_ENABLE
|
||||
|
||||
|
@ -2678,8 +2866,8 @@ void loop(void) {
|
|||
boot = false;
|
||||
} else {
|
||||
mqttLog(String(
|
||||
F("IRMQTTServer just (re)connected to MQTT. "
|
||||
"Lost connection about ")
|
||||
String(F("IRMQTTServer just (re)connected to MQTT. "
|
||||
"Lost connection about "))
|
||||
+ timeSince(lastConnectedTime)).c_str());
|
||||
}
|
||||
lastConnectedTime = now;
|
||||
|
@ -2715,6 +2903,29 @@ void loop(void) {
|
|||
}
|
||||
// Periodically send all of the climate state via MQTT.
|
||||
doBroadcast(&lastBroadcast, kBroadcastPeriodMs, climate, false, false);
|
||||
#if SHT3X_SUPPORT
|
||||
// Check if it's time to read the SHT3x sensor.
|
||||
if (statSensorReadTime.elapsed() > SHT3X_CHECK_FREQ * 1000) {
|
||||
byte result = TemperatureSensor.get();
|
||||
if (result == 0) {
|
||||
// Success
|
||||
float temp = TemperatureSensor.cTemp;
|
||||
// XXX Convert units
|
||||
float humidity = TemperatureSensor.humidity;
|
||||
// Publish the temp and humidity to MQTT.
|
||||
String mqttTempTopic = MqttSensorStat + KEY_TEMP;
|
||||
String mqttHumidityTopic = MqttSensorStat + KEY_HUMIDITY;
|
||||
mqtt_client.publish(mqttTempTopic.c_str(), String(temp).c_str());
|
||||
mqtt_client.publish(mqttHumidityTopic.c_str(),
|
||||
String(humidity).c_str());
|
||||
} else {
|
||||
// Error
|
||||
mqttLog((String(F("SHT3x sensor read error: ")) +
|
||||
String(result)).c_str());
|
||||
}
|
||||
statSensorReadTime.reset();
|
||||
}
|
||||
#endif // SHT3X_SUPPORT
|
||||
}
|
||||
#endif // MQTT_ENABLE
|
||||
#if IR_RX
|
||||
|
@ -2934,6 +3145,7 @@ void sendJsonState(const stdAc::state_t state, const String topic,
|
|||
DynamicJsonDocument json(kJsonAcStateMaxSize);
|
||||
json[KEY_PROTOCOL] = typeToString(state.protocol);
|
||||
json[KEY_MODEL] = state.model;
|
||||
json[KEY_COMMAND] = IRac::commandToString(state.command);
|
||||
json[KEY_POWER] = IRac::boolToString(state.power);
|
||||
json[KEY_MODE] = IRac::opmodeToString(state.mode, ha_mode);
|
||||
// Home Assistant wants mode to be off if power is also off & vice-versa.
|
||||
|
@ -2943,10 +3155,12 @@ void sendJsonState(const stdAc::state_t state, const String topic,
|
|||
}
|
||||
json[KEY_CELSIUS] = IRac::boolToString(state.celsius);
|
||||
json[KEY_TEMP] = state.degrees;
|
||||
json[KEY_SENSORTEMP] = state.sensorTemperature;
|
||||
json[KEY_FANSPEED] = IRac::fanspeedToString(state.fanspeed);
|
||||
json[KEY_SWINGV] = IRac::swingvToString(state.swingv);
|
||||
json[KEY_SWINGH] = IRac::swinghToString(state.swingh);
|
||||
json[KEY_QUIET] = IRac::boolToString(state.quiet);
|
||||
json[KEY_IFEEL] = IRac::boolToString(state.iFeel);
|
||||
json[KEY_TURBO] = IRac::boolToString(state.turbo);
|
||||
json[KEY_ECONO] = IRac::boolToString(state.econo);
|
||||
json[KEY_LIGHT] = IRac::boolToString(state.light);
|
||||
|
@ -2984,6 +3198,10 @@ stdAc::state_t jsonToState(const stdAc::state_t current, const char *str) {
|
|||
result.model = IRac::strToModel(json[KEY_MODEL].as<char*>());
|
||||
else if (validJsonInt(json, KEY_MODEL))
|
||||
result.model = json[KEY_MODEL];
|
||||
if (validJsonStr(json, KEY_COMMAND))
|
||||
result.command = IRac::strToCommand(json[KEY_COMMAND].as<char*>());
|
||||
else if (validJsonInt(json, KEY_COMMAND))
|
||||
result.command = json[KEY_COMMAND];
|
||||
if (validJsonStr(json, KEY_MODE))
|
||||
result.mode = IRac::strToOpmode(json[KEY_MODE]);
|
||||
if (validJsonStr(json, KEY_FANSPEED))
|
||||
|
@ -2994,10 +3212,14 @@ stdAc::state_t jsonToState(const stdAc::state_t current, const char *str) {
|
|||
result.swingh = IRac::strToSwingH(json[KEY_SWINGH]);
|
||||
if (json.containsKey(KEY_TEMP))
|
||||
result.degrees = json[KEY_TEMP];
|
||||
if (json.containsKey(KEY_SENSORTEMP))
|
||||
result.sensorTemperature = json[KEY_SENSORTEMP];
|
||||
if (validJsonInt(json, KEY_SLEEP))
|
||||
result.sleep = json[KEY_SLEEP];
|
||||
if (validJsonStr(json, KEY_POWER))
|
||||
result.power = IRac::strToBool(json[KEY_POWER]);
|
||||
if (validJsonStr(json, KEY_IFEEL))
|
||||
result.iFeel = IRac::strToBool(json[KEY_IFEEL]);
|
||||
if (validJsonStr(json, KEY_QUIET))
|
||||
result.quiet = IRac::strToBool(json[KEY_QUIET]);
|
||||
if (validJsonStr(json, KEY_TURBO))
|
||||
|
@ -3029,6 +3251,8 @@ void updateClimate(stdAc::state_t *state, const String str,
|
|||
state->protocol = strToDecodeType(payload.c_str());
|
||||
} else if (str.equals(prefix + F(KEY_MODEL))) {
|
||||
state->model = IRac::strToModel(payload.c_str());
|
||||
} else if (str.equals(prefix + F(KEY_COMMAND))) {
|
||||
state->command = IRac::strToCommandType(payload.c_str());
|
||||
} else if (str.equals(prefix + F(KEY_POWER))) {
|
||||
state->power = IRac::strToBool(payload.c_str());
|
||||
#if MQTT_CLIMATE_HA_MODE
|
||||
|
@ -3039,16 +3263,32 @@ void updateClimate(stdAc::state_t *state, const String str,
|
|||
state->mode = IRac::strToOpmode(payload.c_str());
|
||||
#if MQTT_CLIMATE_HA_MODE
|
||||
// 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;
|
||||
if (state->mode == stdAc::opmode_t::kOff) {
|
||||
state->power = false;
|
||||
} else {
|
||||
state->power = true;
|
||||
}
|
||||
#endif // MQTT_CLIMATE_HA_MODE
|
||||
} else if (str.equals(prefix + F(KEY_TEMP))) {
|
||||
state->degrees = payload.toFloat();
|
||||
} else if (str.equals(prefix + F(KEY_SENSORTEMP))) {
|
||||
state->sensorTemperature = payload.toFloat();
|
||||
} else if (str.equals(prefix + F(KEY_SENSORTEMP_DISABLED))) {
|
||||
// The "disabled" html form field appears after the actual sensorTemp field
|
||||
// and the spec guarantees the form POST field order preserves body order
|
||||
// => this will always execute after KEY_SENSORTEMP has been parsed already
|
||||
if (IRac::strToBool(payload.c_str())) {
|
||||
// UI control was disabled, ignore the value
|
||||
state->sensorTemperature = kNoTempValue;
|
||||
}
|
||||
} else if (str.equals(prefix + F(KEY_FANSPEED))) {
|
||||
state->fanspeed = IRac::strToFanspeed(payload.c_str());
|
||||
} else if (str.equals(prefix + F(KEY_SWINGV))) {
|
||||
state->swingv = IRac::strToSwingV(payload.c_str());
|
||||
} else if (str.equals(prefix + F(KEY_SWINGH))) {
|
||||
state->swingh = IRac::strToSwingH(payload.c_str());
|
||||
} else if (str.equals(prefix + F(KEY_IFEEL))) {
|
||||
state->iFeel = IRac::strToBool(payload.c_str());
|
||||
} else if (str.equals(prefix + F(KEY_QUIET))) {
|
||||
state->quiet = IRac::strToBool(payload.c_str());
|
||||
} else if (str.equals(prefix + F(KEY_TURBO))) {
|
||||
|
@ -3086,14 +3326,16 @@ bool sendClimate(const String topic_prefix, const bool retain,
|
|||
diff = true;
|
||||
success &= sendInt(topic_prefix + KEY_MODEL, next.model, retain);
|
||||
}
|
||||
if (prev.command != next.command || forceMQTT) {
|
||||
String command_str = IRac::commandTypeToString(next.command);
|
||||
diff = true;
|
||||
success &= sendString(topic_prefix + KEY_COMMAND, command_str, retain);
|
||||
}
|
||||
#ifdef MQTT_CLIMATE_HA_MODE
|
||||
String mode_str = IRac::opmodeToString(next.mode, MQTT_CLIMATE_HA_MODE);
|
||||
#else // MQTT_CLIMATE_HA_MODE
|
||||
String mode_str = IRac::opmodeToString(next.mode);
|
||||
#endif // MQTT_CLIMATE_HA_MODE
|
||||
// I don't know why, but the modes need to be lower case to work with
|
||||
// Home Assistant & Google Home.
|
||||
mode_str.toLowerCase();
|
||||
#if MQTT_CLIMATE_HA_MODE
|
||||
// Home Assistant want's these two bound together.
|
||||
if (prev.power != next.power || prev.mode != next.mode || forceMQTT) {
|
||||
|
@ -3107,6 +3349,10 @@ bool sendClimate(const String topic_prefix, const bool retain,
|
|||
}
|
||||
if (prev.mode != next.mode || forceMQTT) {
|
||||
#endif // MQTT_CLIMATE_HA_MODE
|
||||
// I don't know why, but the modes need to be lower case to work with
|
||||
// Home Assistant & Google Home.
|
||||
mode_str.toLowerCase();
|
||||
|
||||
success &= sendString(topic_prefix + KEY_MODE, mode_str, retain);
|
||||
diff = true;
|
||||
}
|
||||
|
@ -3118,6 +3364,11 @@ bool sendClimate(const String topic_prefix, const bool retain,
|
|||
diff = true;
|
||||
success &= sendBool(topic_prefix + KEY_CELSIUS, next.celsius, retain);
|
||||
}
|
||||
if (prev.sensorTemperature != next.sensorTemperature || forceMQTT) {
|
||||
diff = true;
|
||||
success &= sendFloat(topic_prefix + KEY_SENSORTEMP,
|
||||
next.sensorTemperature, retain);
|
||||
}
|
||||
if (prev.fanspeed != next.fanspeed || forceMQTT) {
|
||||
diff = true;
|
||||
success &= sendString(topic_prefix + KEY_FANSPEED,
|
||||
|
@ -3133,6 +3384,10 @@ bool sendClimate(const String topic_prefix, const bool retain,
|
|||
success &= sendString(topic_prefix + KEY_SWINGH,
|
||||
IRac::swinghToString(next.swingh), retain);
|
||||
}
|
||||
if (prev.iFeel != next.iFeel || forceMQTT) {
|
||||
diff = true;
|
||||
success &= sendBool(topic_prefix + KEY_IFEEL, next.iFeel, retain);
|
||||
}
|
||||
if (prev.quiet != next.quiet || forceMQTT) {
|
||||
diff = true;
|
||||
success &= sendBool(topic_prefix + KEY_QUIET, next.quiet, retain);
|
||||
|
|
|
@ -15,6 +15,8 @@ lib_deps_builtin =
|
|||
lib_deps_external =
|
||||
PubSubClient@>=2.8.0
|
||||
ArduinoJson@>=6.0
|
||||
# Uncomment the following to enable SHT-3x support.
|
||||
# https://github.com/wemos/WEMOS_SHT3x_Arduino_Library.git
|
||||
|
||||
[common_esp8266]
|
||||
lib_deps_external =
|
||||
|
@ -36,6 +38,14 @@ lib_deps = ${common_esp8266.lib_deps_external}
|
|||
board = d1_mini
|
||||
lib_deps = ${common_esp8266.lib_deps_external}
|
||||
|
||||
[env:d1_mini_noMDNS]
|
||||
board = d1_mini
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DMQTT_SERVER_AUTODETECT_ENABLE=false
|
||||
-DMDNS_ENABLE=false
|
||||
lib_deps = ${common_esp8266.lib_deps_external}
|
||||
|
||||
[env:d1_mini_no_mqtt]
|
||||
board = d1_mini
|
||||
build_flags =
|
||||
|
|
|
@ -20,11 +20,14 @@
|
|||
# Datatypes & Classes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
Config KEYWORD1
|
||||
CoronaSection KEYWORD1
|
||||
IRAirtonAc KEYWORD1
|
||||
IRAirwellAc KEYWORD1
|
||||
IRAmcorAc KEYWORD1
|
||||
IRArgoAC KEYWORD1
|
||||
IRArgoACBase KEYWORD1
|
||||
IRArgoAC_WREM3 KEYWORD1
|
||||
IRBosch144AC KEYWORD1
|
||||
IRCarrierAc64 KEYWORD1
|
||||
IRCoolixAC KEYWORD1
|
||||
|
@ -83,11 +86,21 @@ IRTrumaAc KEYWORD1
|
|||
IRVestelAc KEYWORD1
|
||||
IRVoltas KEYWORD1
|
||||
IRWhirlpoolAc KEYWORD1
|
||||
IRYorkAc KEYWORD1
|
||||
IRac KEYWORD1
|
||||
IRrecv KEYWORD1
|
||||
IRsend KEYWORD1
|
||||
IRtimer KEYWORD1
|
||||
Timer KEYWORD1
|
||||
TimerMs KEYWORD1
|
||||
ac_command_t KEYWORD1
|
||||
argoFan_t KEYWORD1
|
||||
argoFlap_t KEYWORD1
|
||||
argoIrMessageType_t KEYWORD1
|
||||
argoMode_t KEYWORD1
|
||||
argoTimerType_t KEYWORD1
|
||||
argoWeekday KEYWORD1
|
||||
argo_ac_remote_model_t KEYWORD1
|
||||
decode_results KEYWORD1
|
||||
decode_type_t KEYWORD1
|
||||
fanspeed_t KEYWORD1
|
||||
|
@ -116,6 +129,7 @@ whirlpool_ac_remote_model_t KEYWORD1
|
|||
_backupState KEYWORD2
|
||||
_cancelOffTimer KEYWORD2
|
||||
_cancelOnTimer KEYWORD2
|
||||
_checksum KEYWORD2
|
||||
_delayMicroseconds KEYWORD2
|
||||
_getEconoToggle KEYWORD2
|
||||
_getOffTimer KEYWORD2
|
||||
|
@ -137,6 +151,7 @@ _setSleepTimer KEYWORD2
|
|||
_setTemp KEYWORD2
|
||||
_setTime KEYWORD2
|
||||
_setTimer KEYWORD2
|
||||
_stateReset KEYWORD2
|
||||
_toString KEYWORD2
|
||||
_validTolerance KEYWORD2
|
||||
add KEYWORD2
|
||||
|
@ -152,12 +167,17 @@ addSwingHToString KEYWORD2
|
|||
addSwingVToString KEYWORD2
|
||||
addTempFloatToString KEYWORD2
|
||||
addTempToString KEYWORD2
|
||||
addTimerModeToString KEYWORD2
|
||||
addToggleToString KEYWORD2
|
||||
adjustRepeat KEYWORD2
|
||||
airton KEYWORD2
|
||||
airwell KEYWORD2
|
||||
amcor KEYWORD2
|
||||
argo KEYWORD2
|
||||
argoWrem3_ACCommand KEYWORD2
|
||||
argoWrem3_ConfigSet KEYWORD2
|
||||
argoWrem3_SetTimer KEYWORD2
|
||||
argoWrem3_iFeelReport KEYWORD2
|
||||
bcdToUint8 KEYWORD2
|
||||
begin KEYWORD2
|
||||
boolToString KEYWORD2
|
||||
|
@ -178,6 +198,7 @@ cancelOnTimer KEYWORD2
|
|||
cancelTimers KEYWORD2
|
||||
carrier64 KEYWORD2
|
||||
celsiusToFahrenheit KEYWORD2
|
||||
channelToString KEYWORD2
|
||||
checkInvertedBytePairs KEYWORD2
|
||||
checkSum KEYWORD2
|
||||
checkZjsSig KEYWORD2
|
||||
|
@ -189,6 +210,7 @@ clearPowerSpecial KEYWORD2
|
|||
clearSensorTemp KEYWORD2
|
||||
clearSleepTimerFlag KEYWORD2
|
||||
cmpStates KEYWORD2
|
||||
commandTypeToString KEYWORD2
|
||||
compare KEYWORD2
|
||||
convertFan KEYWORD2
|
||||
convertMode KEYWORD2
|
||||
|
@ -209,12 +231,15 @@ daikin176 KEYWORD2
|
|||
daikin2 KEYWORD2
|
||||
daikin216 KEYWORD2
|
||||
daikin64 KEYWORD2
|
||||
dayToString KEYWORD2
|
||||
daysBitmaskToString KEYWORD2
|
||||
decode KEYWORD2
|
||||
decodeAirton KEYWORD2
|
||||
decodeAirwell KEYWORD2
|
||||
decodeAiwaRCT501 KEYWORD2
|
||||
decodeAmcor KEYWORD2
|
||||
decodeArgo KEYWORD2
|
||||
decodeArgoWREM3 KEYWORD2
|
||||
decodeArris KEYWORD2
|
||||
decodeBosch144 KEYWORD2
|
||||
decodeBose KEYWORD2
|
||||
|
@ -223,6 +248,7 @@ decodeCarrierAC KEYWORD2
|
|||
decodeCarrierAC128 KEYWORD2
|
||||
decodeCarrierAC40 KEYWORD2
|
||||
decodeCarrierAC64 KEYWORD2
|
||||
decodeCarrierAC84 KEYWORD2
|
||||
decodeClimaButler KEYWORD2
|
||||
decodeCoolix48 KEYWORD2
|
||||
decodeCoronaAc KEYWORD2
|
||||
|
@ -247,6 +273,7 @@ decodeEpson KEYWORD2
|
|||
decodeFujitsuAC KEYWORD2
|
||||
decodeGICable KEYWORD2
|
||||
decodeGoodweather KEYWORD2
|
||||
decodeGorenje KEYWORD2
|
||||
decodeGree KEYWORD2
|
||||
decodeHaierAC KEYWORD2
|
||||
decodeHaierAC160 KEYWORD2
|
||||
|
@ -318,7 +345,9 @@ decodeVestelAc KEYWORD2
|
|||
decodeVoltas KEYWORD2
|
||||
decodeWhirlpoolAC KEYWORD2
|
||||
decodeWhynter KEYWORD2
|
||||
decodeWowwee KEYWORD2
|
||||
decodeXmp KEYWORD2
|
||||
decodeYork KEYWORD2
|
||||
decodeZepeal KEYWORD2
|
||||
defaultBits KEYWORD2
|
||||
delonghiac KEYWORD2
|
||||
|
@ -371,6 +400,8 @@ getBreeze KEYWORD2
|
|||
getBufSize KEYWORD2
|
||||
getButton KEYWORD2
|
||||
getCelsius KEYWORD2
|
||||
getChannel KEYWORD2
|
||||
getChecksum KEYWORD2
|
||||
getClean KEYWORD2
|
||||
getCleanToggle KEYWORD2
|
||||
getClock KEYWORD2
|
||||
|
@ -381,10 +412,13 @@ getCorrectedRawLength KEYWORD2
|
|||
getCurrTime KEYWORD2
|
||||
getCurrentDay KEYWORD2
|
||||
getCurrentTime KEYWORD2
|
||||
getCurrentTimeMinutes KEYWORD2
|
||||
getDelayTimerMinutes KEYWORD2
|
||||
getDirectIndirect KEYWORD2
|
||||
getDisplay KEYWORD2
|
||||
getDisplayTempSource KEYWORD2
|
||||
getDryGrade KEYWORD2
|
||||
getEco KEYWORD2
|
||||
getEcocool KEYWORD2
|
||||
getEcono KEYWORD2
|
||||
getEconoToggle KEYWORD2
|
||||
|
@ -438,8 +472,10 @@ getPurify KEYWORD2
|
|||
getQuiet KEYWORD2
|
||||
getRClevel KEYWORD2
|
||||
getRaw KEYWORD2
|
||||
getRoomTemp KEYWORD2
|
||||
getRawByteLength KEYWORD2
|
||||
getSave KEYWORD2
|
||||
getScheduleTimerStartMinutes KEYWORD2
|
||||
getScheduleTimerStopMinutes KEYWORD2
|
||||
getSectionByte KEYWORD2
|
||||
getSectionChecksum KEYWORD2
|
||||
getSensor KEYWORD2
|
||||
|
@ -455,6 +491,7 @@ getSpeed KEYWORD2
|
|||
getStartClock KEYWORD2
|
||||
getState KEYWORD2
|
||||
getStateLength KEYWORD2
|
||||
getStateLengthForIrMsgType KEYWORD2
|
||||
getStatePrev KEYWORD2
|
||||
getStopClock KEYWORD2
|
||||
getSupercool KEYWORD2
|
||||
|
@ -476,6 +513,7 @@ getTempUnit KEYWORD2
|
|||
getTempUnits KEYWORD2
|
||||
getTime KEYWORD2
|
||||
getTimer KEYWORD2
|
||||
getTimerActiveDaysBitmap KEYWORD2
|
||||
getTimerEnabled KEYWORD2
|
||||
getTimerMode KEYWORD2
|
||||
getTimerTime KEYWORD2
|
||||
|
@ -511,6 +549,7 @@ handleToggles KEYWORD2
|
|||
hasACState KEYWORD2
|
||||
hasInvertedStates KEYWORD2
|
||||
hasStateChanged KEYWORD2
|
||||
hasValidPreamble KEYWORD2
|
||||
hitachi KEYWORD2
|
||||
hitachi1 KEYWORD2
|
||||
hitachi264 KEYWORD2
|
||||
|
@ -521,6 +560,7 @@ htmlEscape KEYWORD2
|
|||
initState KEYWORD2
|
||||
int64ToString KEYWORD2
|
||||
invertBits KEYWORD2
|
||||
irCommandTypeToString KEYWORD2
|
||||
is8CHeatToggle KEYWORD2
|
||||
isCleanToggle KEYWORD2
|
||||
isEconoToggle KEYWORD2
|
||||
|
@ -546,6 +586,7 @@ isTimeCommand KEYWORD2
|
|||
isTimerActive KEYWORD2
|
||||
isTurboToggle KEYWORD2
|
||||
isValidLgAc KEYWORD2
|
||||
isValidWrem3Message KEYWORD2
|
||||
isVaneSwingV KEYWORD2
|
||||
kelon KEYWORD2
|
||||
kelvinator KEYWORD2
|
||||
|
@ -606,6 +647,7 @@ sendAirwell KEYWORD2
|
|||
sendAiwaRCT501 KEYWORD2
|
||||
sendAmcor KEYWORD2
|
||||
sendArgo KEYWORD2
|
||||
sendArgoWREM3 KEYWORD2
|
||||
sendArris KEYWORD2
|
||||
sendBosch144 KEYWORD2
|
||||
sendBose KEYWORD2
|
||||
|
@ -614,6 +656,7 @@ sendCarrierAC KEYWORD2
|
|||
sendCarrierAC128 KEYWORD2
|
||||
sendCarrierAC40 KEYWORD2
|
||||
sendCarrierAC64 KEYWORD2
|
||||
sendCarrierAC84 KEYWORD2
|
||||
sendClimaButler KEYWORD2
|
||||
sendCoolix48 KEYWORD2
|
||||
sendCoronaAc KEYWORD2
|
||||
|
@ -642,6 +685,7 @@ sendGC KEYWORD2
|
|||
sendGICable KEYWORD2
|
||||
sendGeneric KEYWORD2
|
||||
sendGoodweather KEYWORD2
|
||||
sendGorenje KEYWORD2
|
||||
sendGree KEYWORD2
|
||||
sendHaierAC KEYWORD2
|
||||
sendHaierAC160 KEYWORD2
|
||||
|
@ -728,7 +772,9 @@ sendVestelAc KEYWORD2
|
|||
sendVoltas KEYWORD2
|
||||
sendWhirlpoolAC KEYWORD2
|
||||
sendWhynter KEYWORD2
|
||||
sendWowwee KEYWORD2
|
||||
sendXmp KEYWORD2
|
||||
sendYork KEYWORD2
|
||||
sendZepeal KEYWORD2
|
||||
serialPrintUint64 KEYWORD2
|
||||
set10CHeat KEYWORD2
|
||||
|
@ -745,6 +791,7 @@ setBoost KEYWORD2
|
|||
setBreeze KEYWORD2
|
||||
setButton KEYWORD2
|
||||
setCelsius KEYWORD2
|
||||
setChannel KEYWORD2
|
||||
setCheckSumS3 KEYWORD2
|
||||
setClean KEYWORD2
|
||||
setCleanToggle KEYWORD2
|
||||
|
@ -752,13 +799,18 @@ setClock KEYWORD2
|
|||
setCmd KEYWORD2
|
||||
setComfort KEYWORD2
|
||||
setCommand KEYWORD2
|
||||
setConfigEntry KEYWORD2
|
||||
setCurrTime KEYWORD2
|
||||
setCurrentDay KEYWORD2
|
||||
setCurrentDayOfWeek KEYWORD2
|
||||
setCurrentTime KEYWORD2
|
||||
setCurrentTimeMinutes KEYWORD2
|
||||
setDelayTimerMinutes KEYWORD2
|
||||
setDirectIndirect KEYWORD2
|
||||
setDisplay KEYWORD2
|
||||
setDisplayTempSource KEYWORD2
|
||||
setDryGrade KEYWORD2
|
||||
setEco KEYWORD2
|
||||
setEcocool KEYWORD2
|
||||
setEcono KEYWORD2
|
||||
setEconoToggle KEYWORD2
|
||||
|
@ -790,6 +842,7 @@ setLight KEYWORD2
|
|||
setLightToggle KEYWORD2
|
||||
setLock KEYWORD2
|
||||
setMax KEYWORD2
|
||||
setMessageType KEYWORD2
|
||||
setMode KEYWORD2
|
||||
setModel KEYWORD2
|
||||
setMold KEYWORD2
|
||||
|
@ -813,8 +866,10 @@ setPowerful KEYWORD2
|
|||
setPurify KEYWORD2
|
||||
setQuiet KEYWORD2
|
||||
setRaw KEYWORD2
|
||||
setRoomTemp KEYWORD2
|
||||
setSave KEYWORD2
|
||||
setScheduleTimerActiveDays KEYWORD2
|
||||
setScheduleTimerStartMinutes KEYWORD2
|
||||
setScheduleTimerStopMinutes KEYWORD2
|
||||
setSensor KEYWORD2
|
||||
setSensorTemp KEYWORD2
|
||||
setSensorTempRaw KEYWORD2
|
||||
|
@ -917,6 +972,7 @@ xorBytes KEYWORD2
|
|||
A705 LITERAL1
|
||||
A903 LITERAL1
|
||||
A907 LITERAL1
|
||||
AC_CONTROL LITERAL1
|
||||
AIRTON LITERAL1
|
||||
AIRWELL LITERAL1
|
||||
AIWA_RC_T501 LITERAL1
|
||||
|
@ -956,14 +1012,18 @@ ARREB1E LITERAL1
|
|||
ARREW4E LITERAL1
|
||||
ARRIS LITERAL1
|
||||
ARRY4 LITERAL1
|
||||
AUTO LITERAL1
|
||||
BOSCH144 LITERAL1
|
||||
BOSE LITERAL1
|
||||
CARRIER_AC LITERAL1
|
||||
CARRIER_AC128 LITERAL1
|
||||
CARRIER_AC40 LITERAL1
|
||||
CARRIER_AC64 LITERAL1
|
||||
CARRIER_AC84 LITERAL1
|
||||
CARRIER_AC_BITS LITERAL1
|
||||
CLIMABUTLER LITERAL1
|
||||
CONFIG_PARAM_SET LITERAL1
|
||||
COOL LITERAL1
|
||||
COOLIX LITERAL1
|
||||
COOLIX48 LITERAL1
|
||||
COOLIX_BITS LITERAL1
|
||||
|
@ -1003,6 +1063,7 @@ DECODE_CARRIER_AC LITERAL1
|
|||
DECODE_CARRIER_AC128 LITERAL1
|
||||
DECODE_CARRIER_AC40 LITERAL1
|
||||
DECODE_CARRIER_AC64 LITERAL1
|
||||
DECODE_CARRIER_AC84 LITERAL1
|
||||
DECODE_CLIMABUTLER LITERAL1
|
||||
DECODE_COOLIX LITERAL1
|
||||
DECODE_COOLIX48 LITERAL1
|
||||
|
@ -1029,6 +1090,7 @@ DECODE_FUJITSU_AC LITERAL1
|
|||
DECODE_GICABLE LITERAL1
|
||||
DECODE_GLOBALCACHE LITERAL1
|
||||
DECODE_GOODWEATHER LITERAL1
|
||||
DECODE_GORENJE LITERAL1
|
||||
DECODE_GREE LITERAL1
|
||||
DECODE_HAIER_AC LITERAL1
|
||||
DECODE_HAIER_AC160 LITERAL1
|
||||
|
@ -1105,8 +1167,11 @@ DECODE_VESTEL_AC LITERAL1
|
|||
DECODE_VOLTAS LITERAL1
|
||||
DECODE_WHIRLPOOL_AC LITERAL1
|
||||
DECODE_WHYNTER LITERAL1
|
||||
DECODE_WOWWEE LITERAL1
|
||||
DECODE_XMP LITERAL1
|
||||
DECODE_YORK LITERAL1
|
||||
DECODE_ZEPEAL LITERAL1
|
||||
DELAY_TIMER LITERAL1
|
||||
DELONGHI_AC LITERAL1
|
||||
DENON LITERAL1
|
||||
DENON_48_BITS LITERAL1
|
||||
|
@ -1117,11 +1182,29 @@ DG11J191 LITERAL1
|
|||
DISH LITERAL1
|
||||
DISH_BITS LITERAL1
|
||||
DOSHISHA LITERAL1
|
||||
DRY LITERAL1
|
||||
ECOCLIM LITERAL1
|
||||
ELECTRA_AC LITERAL1
|
||||
ELITESCREENS LITERAL1
|
||||
ENABLE_NOISE_FILTER_OPTION LITERAL1
|
||||
EPSON LITERAL1
|
||||
FAN LITERAL1
|
||||
FAN_AUTO LITERAL1
|
||||
FAN_HIGH LITERAL1
|
||||
FAN_HIGHEST LITERAL1
|
||||
FAN_LOW LITERAL1
|
||||
FAN_LOWER LITERAL1
|
||||
FAN_LOWEST LITERAL1
|
||||
FAN_MEDIUM LITERAL1
|
||||
FLAP_1 LITERAL1
|
||||
FLAP_2 LITERAL1
|
||||
FLAP_3 LITERAL1
|
||||
FLAP_4 LITERAL1
|
||||
FLAP_5 LITERAL1
|
||||
FLAP_6 LITERAL1
|
||||
FLAP_AUTO LITERAL1
|
||||
FLAP_FULL LITERAL1
|
||||
FRIDAY LITERAL1
|
||||
FUJITSU_AC LITERAL1
|
||||
FUJITSU_AC_BITS LITERAL1
|
||||
FUJITSU_AC_CMD_STAY_ON LITERAL1
|
||||
|
@ -1154,6 +1237,7 @@ GICABLE LITERAL1
|
|||
GICABLE_BITS LITERAL1
|
||||
GLOBALCACHE LITERAL1
|
||||
GOODWEATHER LITERAL1
|
||||
GORENJE LITERAL1
|
||||
GREE LITERAL1
|
||||
GREE_AUTO LITERAL1
|
||||
GREE_COOL LITERAL1
|
||||
|
@ -1233,6 +1317,7 @@ HAIER_AC_YRW02_SWING_MIDDLE LITERAL1
|
|||
HAIER_AC_YRW02_SWING_OFF LITERAL1
|
||||
HAIER_AC_YRW02_SWING_TOP LITERAL1
|
||||
HAIER_AC_YRW02_TURBO_OFF LITERAL1
|
||||
HEAT LITERAL1
|
||||
HIGH LITERAL1
|
||||
HITACHI_AC LITERAL1
|
||||
HITACHI_AC1 LITERAL1
|
||||
|
@ -1250,7 +1335,7 @@ HITACHI_AC344 LITERAL1
|
|||
HITACHI_AC424 LITERAL1
|
||||
HITACHI_AC_BITS LITERAL1
|
||||
HITACHI_AC_STATE_LENGTH LITERAL1
|
||||
ICACHE_RAM_ATTR LITERAL1
|
||||
IFEEL_TEMP_REPORT LITERAL1
|
||||
INAX LITERAL1
|
||||
JVC LITERAL1
|
||||
JVC_BITS LITERAL1
|
||||
|
@ -1325,6 +1410,7 @@ MITSUBISHI_AC_VANE_AUTO_MOVE LITERAL1
|
|||
MITSUBISHI_BITS LITERAL1
|
||||
MITSUBISHI_HEAVY_152 LITERAL1
|
||||
MITSUBISHI_HEAVY_88 LITERAL1
|
||||
MONDAY LITERAL1
|
||||
MULTIBRACKETS LITERAL1
|
||||
MWM LITERAL1
|
||||
NEC LITERAL1
|
||||
|
@ -1334,6 +1420,7 @@ NEOCLIMA LITERAL1
|
|||
NIKAI LITERAL1
|
||||
NIKAI_BITS LITERAL1
|
||||
NOTHING LITERAL1
|
||||
NO_TIMER LITERAL1
|
||||
ONCE LITERAL1
|
||||
PANASONIC LITERAL1
|
||||
PANASONIC_AC LITERAL1
|
||||
|
@ -1356,6 +1443,8 @@ RCMM_BITS LITERAL1
|
|||
RHOSS LITERAL1
|
||||
R_LT0541_HTA_A LITERAL1
|
||||
R_LT0541_HTA_B LITERAL1
|
||||
SAC_WREM2 LITERAL1
|
||||
SAC_WREM3 LITERAL1
|
||||
SAMSUNG LITERAL1
|
||||
SAMSUNG36 LITERAL1
|
||||
SAMSUNG_AC LITERAL1
|
||||
|
@ -1367,6 +1456,10 @@ SANYO_AC88 LITERAL1
|
|||
SANYO_LC7461 LITERAL1
|
||||
SANYO_LC7461_BITS LITERAL1
|
||||
SANYO_SA8650B_BITS LITERAL1
|
||||
SATURDAY LITERAL1
|
||||
SCHEDULE_TIMER_1 LITERAL1
|
||||
SCHEDULE_TIMER_2 LITERAL1
|
||||
SCHEDULE_TIMER_3 LITERAL1
|
||||
SEND_AIRTON LITERAL1
|
||||
SEND_AIRWELL LITERAL1
|
||||
SEND_AIWA_RC_T501 LITERAL1
|
||||
|
@ -1379,6 +1472,7 @@ SEND_CARRIER_AC LITERAL1
|
|||
SEND_CARRIER_AC128 LITERAL1
|
||||
SEND_CARRIER_AC40 LITERAL1
|
||||
SEND_CARRIER_AC64 LITERAL1
|
||||
SEND_CARRIER_AC84 LITERAL1
|
||||
SEND_CLIMABUTLER LITERAL1
|
||||
SEND_COOLIX LITERAL1
|
||||
SEND_COOLIX48 LITERAL1
|
||||
|
@ -1405,6 +1499,7 @@ SEND_FUJITSU_AC LITERAL1
|
|||
SEND_GICABLE LITERAL1
|
||||
SEND_GLOBALCACHE LITERAL1
|
||||
SEND_GOODWEATHER LITERAL1
|
||||
SEND_GORENJE LITERAL1
|
||||
SEND_GREE LITERAL1
|
||||
SEND_HAIER_AC LITERAL1
|
||||
SEND_HAIER_AC160 LITERAL1
|
||||
|
@ -1481,7 +1576,9 @@ SEND_VESTEL_AC LITERAL1
|
|||
SEND_VOLTAS LITERAL1
|
||||
SEND_WHIRLPOOL_AC LITERAL1
|
||||
SEND_WHYNTER LITERAL1
|
||||
SEND_WOWWEE LITERAL1
|
||||
SEND_XMP LITERAL1
|
||||
SEND_YORK LITERAL1
|
||||
SEND_ZEPEAL LITERAL1
|
||||
SHARP LITERAL1
|
||||
SHARP_AC LITERAL1
|
||||
|
@ -1493,6 +1590,7 @@ SONY_12_BITS LITERAL1
|
|||
SONY_15_BITS LITERAL1
|
||||
SONY_20_BITS LITERAL1
|
||||
SONY_38K LITERAL1
|
||||
SUNDAY LITERAL1
|
||||
SYMPHONY LITERAL1
|
||||
TAC09CHSD LITERAL1
|
||||
TCL112AC LITERAL1
|
||||
|
@ -1500,7 +1598,9 @@ TCL96AC LITERAL1
|
|||
TECHNIBEL_AC LITERAL1
|
||||
TECO LITERAL1
|
||||
TEKNOPOINT LITERAL1
|
||||
THURSDAY LITERAL1
|
||||
TIMEOUT_MS LITERAL1
|
||||
TIMER_COMMAND LITERAL1
|
||||
TOSHIBA_AC LITERAL1
|
||||
TOSHIBA_AC_AUTO LITERAL1
|
||||
TOSHIBA_AC_COOL LITERAL1
|
||||
|
@ -1528,6 +1628,7 @@ TROTEC_MAX_TEMP LITERAL1
|
|||
TROTEC_MAX_TIMER LITERAL1
|
||||
TROTEC_MIN_TEMP LITERAL1
|
||||
TRUMA LITERAL1
|
||||
TUESDAY LITERAL1
|
||||
UNKNOWN LITERAL1
|
||||
UNUSED LITERAL1
|
||||
USE_IRAM_ATTR LITERAL1
|
||||
|
@ -1535,12 +1636,15 @@ V9014557_A LITERAL1
|
|||
V9014557_B LITERAL1
|
||||
VESTEL_AC LITERAL1
|
||||
VOLTAS LITERAL1
|
||||
WEDNESDAY LITERAL1
|
||||
WHIRLPOOL_AC LITERAL1
|
||||
WHYNTER LITERAL1
|
||||
WHYNTER_BITS LITERAL1
|
||||
WOWWEE LITERAL1
|
||||
XMP LITERAL1
|
||||
YAW1F LITERAL1
|
||||
YBOFB LITERAL1
|
||||
YORK LITERAL1
|
||||
YX1FSF LITERAL1
|
||||
ZEPEAL LITERAL1
|
||||
k0Str LITERAL1
|
||||
|
@ -1649,6 +1753,10 @@ kAmcorVentOn LITERAL1
|
|||
kAmcorZeroMark LITERAL1
|
||||
kAmcorZeroSpace LITERAL1
|
||||
kArdb1Str LITERAL1
|
||||
kArgo3AcControlStateLength LITERAL1
|
||||
kArgo3ConfigStateLength LITERAL1
|
||||
kArgo3TimerStateLength LITERAL1
|
||||
kArgo3iFeelReportStateLength LITERAL1
|
||||
kArgoAuto LITERAL1
|
||||
kArgoBitMark LITERAL1
|
||||
kArgoBits LITERAL1
|
||||
|
@ -1667,6 +1775,7 @@ kArgoFlap5 LITERAL1
|
|||
kArgoFlap6 LITERAL1
|
||||
kArgoFlapAuto LITERAL1
|
||||
kArgoFlapFull LITERAL1
|
||||
kArgoFrequency LITERAL1
|
||||
kArgoGap LITERAL1
|
||||
kArgoHdrMark LITERAL1
|
||||
kArgoHdrSpace LITERAL1
|
||||
|
@ -1674,13 +1783,26 @@ kArgoHeat LITERAL1
|
|||
kArgoHeatAuto LITERAL1
|
||||
kArgoHeatBit LITERAL1
|
||||
kArgoHeatBlink LITERAL1
|
||||
kArgoMaxChannel LITERAL1
|
||||
kArgoMaxRoomTemp LITERAL1
|
||||
kArgoMaxTemp LITERAL1
|
||||
kArgoMinTemp LITERAL1
|
||||
kArgoOff LITERAL1
|
||||
kArgoOneSpace LITERAL1
|
||||
kArgoPost LITERAL1
|
||||
kArgoPreamble1 LITERAL1
|
||||
kArgoPreamble2 LITERAL1
|
||||
kArgoSensorCheck LITERAL1
|
||||
kArgoSensorFixed LITERAL1
|
||||
kArgoShortBits LITERAL1
|
||||
kArgoShortStateLength LITERAL1
|
||||
kArgoStateLength LITERAL1
|
||||
kArgoTempDelta LITERAL1
|
||||
kArgoWrem2Str LITERAL1
|
||||
kArgoWrem3Postfix_ACControl LITERAL1
|
||||
kArgoWrem3Postfix_Timer LITERAL1
|
||||
kArgoWrem3Preamble LITERAL1
|
||||
kArgoWrem3Str LITERAL1
|
||||
kArgoZeroSpace LITERAL1
|
||||
kArjw2Str LITERAL1
|
||||
kArrah2eStr LITERAL1
|
||||
|
@ -1785,6 +1907,16 @@ kCarrierAc64OneSpace LITERAL1
|
|||
kCarrierAc64TimerMax LITERAL1
|
||||
kCarrierAc64TimerMin LITERAL1
|
||||
kCarrierAc64ZeroSpace LITERAL1
|
||||
kCarrierAc84Bits LITERAL1
|
||||
kCarrierAc84ExtraBits LITERAL1
|
||||
kCarrierAc84ExtraTolerance LITERAL1
|
||||
kCarrierAc84Gap LITERAL1
|
||||
kCarrierAc84HdrMark LITERAL1
|
||||
kCarrierAc84HdrSpace LITERAL1
|
||||
kCarrierAc84MinRepeat LITERAL1
|
||||
kCarrierAc84One LITERAL1
|
||||
kCarrierAc84StateLength LITERAL1
|
||||
kCarrierAc84Zero LITERAL1
|
||||
kCarrierAcBitMark LITERAL1
|
||||
kCarrierAcBits LITERAL1
|
||||
kCarrierAcFreq LITERAL1
|
||||
|
@ -1798,6 +1930,7 @@ kCeilingStr LITERAL1
|
|||
kCelsiusFahrenheitStr LITERAL1
|
||||
kCelsiusStr LITERAL1
|
||||
kCentreStr LITERAL1
|
||||
kChStr LITERAL1
|
||||
kChangeStr LITERAL1
|
||||
kCirculateStr LITERAL1
|
||||
kCkpStr LITERAL1
|
||||
|
@ -1816,6 +1949,10 @@ kColonSpaceStr LITERAL1
|
|||
kComfortStr LITERAL1
|
||||
kCommaSpaceStr LITERAL1
|
||||
kCommandStr LITERAL1
|
||||
kConfigCommand LITERAL1
|
||||
kConfigCommandStr LITERAL1
|
||||
kControlCommand LITERAL1
|
||||
kControlCommandStr LITERAL1
|
||||
kCool LITERAL1
|
||||
kCoolStr LITERAL1
|
||||
kCoolingStr LITERAL1
|
||||
|
@ -2413,6 +2550,15 @@ kGoodweatherSwingSlow LITERAL1
|
|||
kGoodweatherTempMax LITERAL1
|
||||
kGoodweatherTempMin LITERAL1
|
||||
kGoodweatherZeroSpace LITERAL1
|
||||
kGorenjeBitMark LITERAL1
|
||||
kGorenjeBits LITERAL1
|
||||
kGorenjeFreq LITERAL1
|
||||
kGorenjeHdrMark LITERAL1
|
||||
kGorenjeHdrSpace LITERAL1
|
||||
kGorenjeMinGap LITERAL1
|
||||
kGorenjeOneSpace LITERAL1
|
||||
kGorenjeTolerance LITERAL1
|
||||
kGorenjeZeroSpace LITERAL1
|
||||
kGpioUnused LITERAL1
|
||||
kGreeAuto LITERAL1
|
||||
kGreeBitMark LITERAL1
|
||||
|
@ -2735,6 +2881,7 @@ kHoldStr LITERAL1
|
|||
kHourStr LITERAL1
|
||||
kHoursStr LITERAL1
|
||||
kHumidStr LITERAL1
|
||||
kIFeelReportStr LITERAL1
|
||||
kIFeelStr LITERAL1
|
||||
kISeeStr LITERAL1
|
||||
kIdStr LITERAL1
|
||||
|
@ -2836,6 +2983,7 @@ kKelvinatorSwingVUpperMiddle LITERAL1
|
|||
kKelvinatorTick LITERAL1
|
||||
kKelvinatorZeroSpace LITERAL1
|
||||
kKelvinatorZeroSpaceTicks LITERAL1
|
||||
kKeyStr LITERAL1
|
||||
kKkg29ac1Str LITERAL1
|
||||
kKkg9ac1Str LITERAL1
|
||||
kLasertagBits LITERAL1
|
||||
|
@ -2846,6 +2994,7 @@ kLasertagMinRepeat LITERAL1
|
|||
kLasertagMinSamples LITERAL1
|
||||
kLasertagTick LITERAL1
|
||||
kLasertagTolerance LITERAL1
|
||||
kLastAcCommandEnum LITERAL1
|
||||
kLastDecodeType LITERAL1
|
||||
kLastFanspeedEnum LITERAL1
|
||||
kLastOpmodeEnum LITERAL1
|
||||
|
@ -2983,8 +3132,10 @@ kMaxRightStr LITERAL1
|
|||
kMaxStr LITERAL1
|
||||
kMaxTimeoutMs LITERAL1
|
||||
kMaximumStr LITERAL1
|
||||
kMedHighStr LITERAL1
|
||||
kMedStr LITERAL1
|
||||
kMedium LITERAL1
|
||||
kMediumHigh LITERAL1
|
||||
kMediumStr LITERAL1
|
||||
kMetzAddressBits LITERAL1
|
||||
kMetzBitMark LITERAL1
|
||||
|
@ -3392,6 +3543,7 @@ kNikaiZeroSpaceTicks LITERAL1
|
|||
kNkeStr LITERAL1
|
||||
kNoRepeat LITERAL1
|
||||
kNoStr LITERAL1
|
||||
kNoTempValue LITERAL1
|
||||
kNowStr LITERAL1
|
||||
kOff LITERAL1
|
||||
kOffStr LITERAL1
|
||||
|
@ -3400,6 +3552,8 @@ kOnStr LITERAL1
|
|||
kOnTimerStr LITERAL1
|
||||
kOutsideQuietStr LITERAL1
|
||||
kOutsideStr LITERAL1
|
||||
kPanasonic40Bits LITERAL1
|
||||
kPanasonic40Manufacturer LITERAL1
|
||||
kPanasonicAc32Auto LITERAL1
|
||||
kPanasonicAc32BitMark LITERAL1
|
||||
kPanasonicAc32Bits LITERAL1
|
||||
|
@ -3773,11 +3927,14 @@ kSanyoSa8650bOneMark LITERAL1
|
|||
kSanyoSa8650bRptLength LITERAL1
|
||||
kSanyoSa8650bZeroMark LITERAL1
|
||||
kSaveStr LITERAL1
|
||||
kScheduleStr LITERAL1
|
||||
kSecondStr LITERAL1
|
||||
kSecondsStr LITERAL1
|
||||
kSensorStr LITERAL1
|
||||
kSensorTempReport LITERAL1
|
||||
kSensorTempStr LITERAL1
|
||||
kSetStr LITERAL1
|
||||
kSetTimerCommandStr LITERAL1
|
||||
kSharpAcAuto LITERAL1
|
||||
kSharpAcBitMark LITERAL1
|
||||
kSharpAcBits LITERAL1
|
||||
|
@ -4002,6 +4159,8 @@ kTempUpStr LITERAL1
|
|||
kThreeLetterDayOfWeekStr LITERAL1
|
||||
kTimeSep LITERAL1
|
||||
kTimeoutMs LITERAL1
|
||||
kTimerActiveDaysStr LITERAL1
|
||||
kTimerCommand LITERAL1
|
||||
kTimerModeStr LITERAL1
|
||||
kTimerStr LITERAL1
|
||||
kToggleStr LITERAL1
|
||||
|
@ -4147,10 +4306,13 @@ kTypeStr LITERAL1
|
|||
kUnknownStr LITERAL1
|
||||
kUnknownThreshold LITERAL1
|
||||
kUpStr LITERAL1
|
||||
kUpperMiddle LITERAL1
|
||||
kUpperMiddleStr LITERAL1
|
||||
kUpperStr LITERAL1
|
||||
kUseDefTol LITERAL1
|
||||
kV9014557AStr LITERAL1
|
||||
kV9014557BStr LITERAL1
|
||||
kValueStr LITERAL1
|
||||
kVaneStr LITERAL1
|
||||
kVestelAcAuto LITERAL1
|
||||
kVestelAcBitMark LITERAL1
|
||||
|
@ -4259,6 +4421,14 @@ kWhynterZeroSpaceTicks LITERAL1
|
|||
kWide LITERAL1
|
||||
kWideStr LITERAL1
|
||||
kWifiStr LITERAL1
|
||||
kWowweeBitMark LITERAL1
|
||||
kWowweeBits LITERAL1
|
||||
kWowweeDefaultRepeat LITERAL1
|
||||
kWowweeFreq LITERAL1
|
||||
kWowweeHdrMark LITERAL1
|
||||
kWowweeHdrSpace LITERAL1
|
||||
kWowweeOneSpace LITERAL1
|
||||
kWowweeZeroSpace LITERAL1
|
||||
kXFanStr LITERAL1
|
||||
kXmpBaseSpace LITERAL1
|
||||
kXmpBits LITERAL1
|
||||
|
@ -4274,6 +4444,26 @@ kXmpWordSize LITERAL1
|
|||
kYaw1fStr LITERAL1
|
||||
kYbofbStr LITERAL1
|
||||
kYesStr LITERAL1
|
||||
kYorkAuto LITERAL1
|
||||
kYorkBitMark LITERAL1
|
||||
kYorkBits LITERAL1
|
||||
kYorkCool LITERAL1
|
||||
kYorkDry LITERAL1
|
||||
kYorkFan LITERAL1
|
||||
kYorkFanAuto LITERAL1
|
||||
kYorkFanHigh LITERAL1
|
||||
kYorkFanLow LITERAL1
|
||||
kYorkFanMedium LITERAL1
|
||||
kYorkFreq LITERAL1
|
||||
kYorkHdrMark LITERAL1
|
||||
kYorkHdrSpace LITERAL1
|
||||
kYorkHeat LITERAL1
|
||||
kYorkKnownGoodState LITERAL1
|
||||
kYorkMaxTemp LITERAL1
|
||||
kYorkMinTemp LITERAL1
|
||||
kYorkOneSpace LITERAL1
|
||||
kYorkStateLength LITERAL1
|
||||
kYorkZeroSpace LITERAL1
|
||||
kYx1fsfStr LITERAL1
|
||||
kZepealBits LITERAL1
|
||||
kZepealCommandOffOn LITERAL1
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "IRremoteESP8266",
|
||||
"version": "2.8.4",
|
||||
"version": "2.8.5",
|
||||
"keywords": "infrared, ir, remote, esp8266, esp32",
|
||||
"description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)",
|
||||
"repository":
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name=IRremoteESP8266
|
||||
version=2.8.4
|
||||
version=2.8.5
|
||||
author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff
|
||||
maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto, Christian Nilsson
|
||||
sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef ARDUINO
|
||||
#include <string>
|
||||
#endif
|
||||
#include <cmath>
|
||||
#include "IRsend.h"
|
||||
#include "IRremoteESP8266.h"
|
||||
#include "IRtext.h"
|
||||
|
@ -64,6 +65,36 @@
|
|||
#endif // ESP8266
|
||||
#endif // STRCASECMP
|
||||
|
||||
#ifndef UNIT_TEST
|
||||
#define OUTPUT_DECODE_RESULTS_FOR_UT(ac)
|
||||
#else
|
||||
/* NOTE: THIS IS NOT A DOXYGEN COMMENT (would require ENABLE_PREPROCESSING-YES)
|
||||
/// If compiling for UT *and* a test receiver @c IRrecv is provided via the
|
||||
/// @c _utReceived param, this injects an "output" gadget @c _lastDecodeResults
|
||||
/// into the @c IRAc::sendAc method, so that the UT code may parse the "sent"
|
||||
/// value and drive further assertions
|
||||
///
|
||||
/// @note The @c decode_results "returned" is a shallow copy (empty rawbuf),
|
||||
/// mostly b/c the class does not have a custom/deep copy c-tor
|
||||
/// and defining it would be an overkill for this purpose
|
||||
/// @note For future maintainers: If @c IRAc class is ever refactored to use
|
||||
/// polymorphism (static or dynamic)... this macro should be removed
|
||||
/// and replaced with proper GMock injection.
|
||||
*/
|
||||
#define OUTPUT_DECODE_RESULTS_FOR_UT(ac) \
|
||||
{ \
|
||||
if (_utReceiver) { \
|
||||
_lastDecodeResults = nullptr; \
|
||||
(ac)._irsend.makeDecodeResult(); \
|
||||
if (_utReceiver->decode(&(ac)._irsend.capture)) { \
|
||||
_lastDecodeResults = std::unique_ptr<decode_results>( \
|
||||
new decode_results((ac)._irsend.capture)); \
|
||||
_lastDecodeResults->rawbuf = nullptr; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#endif // UNIT_TEST
|
||||
|
||||
/// Class constructor
|
||||
/// @param[in] pin Gpio pin to use when transmitting IR messages.
|
||||
/// @param[in] inverted true, gpio output defaults to high. false, to low.
|
||||
|
@ -331,6 +362,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
|
|||
#endif
|
||||
#if SEND_VOLTAS
|
||||
case decode_type_t::VOLTAS:
|
||||
#endif
|
||||
#if SEND_YORK
|
||||
case decode_type_t::YORK:
|
||||
#endif
|
||||
case decode_type_t::WHIRLPOOL_AC:
|
||||
return true;
|
||||
|
@ -439,19 +473,27 @@ void IRac::amcor(IRAmcorAc *ac,
|
|||
/// @param[in] on The power setting.
|
||||
/// @param[in] mode The operation mode setting.
|
||||
/// @param[in] degrees The temperature setting in degrees.
|
||||
/// @param[in] sensorTemp The room (iFeel) temperature sensor reading in degrees
|
||||
/// Celsius.
|
||||
/// @param[in] fan The speed setting for the fan.
|
||||
/// @param[in] swingv The vertical swing setting.
|
||||
/// @param[in] iFeel Whether to enable iFeel (remote temp) mode on the A/C unit.
|
||||
/// @param[in] turbo Run the device in turbo/powerful mode.
|
||||
/// @param[in] sleep Nr. of minutes for sleep mode.
|
||||
/// @note -1 is Off, >= 0 is on.
|
||||
void IRac::argo(IRArgoAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const float sensorTemp, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const bool iFeel,
|
||||
const bool turbo, const int16_t sleep) {
|
||||
ac->begin();
|
||||
ac->setPower(on);
|
||||
ac->setMode(ac->convertMode(mode));
|
||||
ac->setTemp(degrees);
|
||||
ac->setTemp(static_cast<uint8_t>(std::round(degrees)));
|
||||
if (sensorTemp != kNoTempValue) {
|
||||
ac->setSensorTemp(static_cast<uint8_t>(std::round(sensorTemp)));
|
||||
}
|
||||
ac->setiFeel(iFeel);
|
||||
ac->setFan(ac->convertFan(fan));
|
||||
ac->setFlap(ac->convertSwingV(swingv));
|
||||
// No Quiet setting available.
|
||||
|
@ -464,6 +506,121 @@ void IRac::argo(IRArgoAC *ac,
|
|||
ac->setNight(sleep >= 0); // Convert to a boolean.
|
||||
ac->send();
|
||||
}
|
||||
|
||||
/// Send an Argo A/C WREM-3 AC **control** message with the supplied settings.
|
||||
/// @param[in, out] ac A Ptr to an IRArgoAC_WREM3 object to use.
|
||||
/// @param[in] on The power setting.
|
||||
/// @param[in] mode The operation mode setting.
|
||||
/// @param[in] degrees The set temperature setting in degrees Celsius.
|
||||
/// @param[in] sensorTemp The room (iFeel) temperature sensor reading in degrees
|
||||
/// Celsius.
|
||||
/// @warning The @c sensorTemp param is assumed to be in 0..255 range (uint8_t)
|
||||
/// The overflow is *not* checked, though.
|
||||
/// @note The value is rounded to nearest integer, rounding halfway cases
|
||||
/// away from zero. E.g. 1.5 [C] becomes 2 [C].
|
||||
/// @param[in] fan The speed setting for the fan.
|
||||
/// @param[in] swingv The vertical swing setting.
|
||||
/// @param[in] iFeel Whether to enable iFeel (remote temp) mode on the A/C unit.
|
||||
/// @param[in] night Enable night mode (raises temp by +1*C after 1h).
|
||||
/// @param[in] econo Enable eco mode (limits power consumed).
|
||||
/// @param[in] turbo Run the device in turbo/powerful mode.
|
||||
/// @param[in] filter Enable filter mode
|
||||
/// @param[in] light Enable device display/LEDs
|
||||
void IRac::argoWrem3_ACCommand(IRArgoAC_WREM3 *ac, const bool on,
|
||||
const stdAc::opmode_t mode, const float degrees, const float sensorTemp,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv, const bool iFeel,
|
||||
const bool night, const bool econo, const bool turbo, const bool filter,
|
||||
const bool light) {
|
||||
ac->begin();
|
||||
ac->setMessageType(argoIrMessageType_t::AC_CONTROL);
|
||||
ac->setPower(on);
|
||||
ac->setMode(ac->convertMode(mode));
|
||||
ac->setTemp(degrees);
|
||||
if (sensorTemp != kNoTempValue) {
|
||||
ac->setSensorTemp(static_cast<uint8_t>(std::round(sensorTemp)));
|
||||
}
|
||||
ac->setiFeel(iFeel);
|
||||
ac->setFan(ac->convertFan(fan));
|
||||
ac->setFlap(ac->convertSwingV(swingv));
|
||||
ac->setNight(night);
|
||||
ac->setEco(econo);
|
||||
ac->setMax(turbo);
|
||||
ac->setFilter(filter);
|
||||
ac->setLight(light);
|
||||
// No Clean setting available.
|
||||
// No Beep setting available - always beeps in this mode :)
|
||||
ac->send();
|
||||
}
|
||||
|
||||
/// Send an Argo A/C WREM-3 iFeel (room temp) silent (no beep) report.
|
||||
/// @param[in, out] ac A Ptr to an IRArgoAC_WREM3 object to use.
|
||||
/// @param[in] sensorTemp The room (iFeel) temperature setting
|
||||
/// in degrees Celsius.
|
||||
/// @warning The @c sensorTemp param is assumed to be in 0..255 range (uint8_t)
|
||||
/// The overflow is *not* checked, though.
|
||||
/// @note The value is rounded to nearest integer, rounding halfway cases
|
||||
/// away from zero. E.g. 1.5 [C] becomes 2 [C].
|
||||
void IRac::argoWrem3_iFeelReport(IRArgoAC_WREM3 *ac, const float sensorTemp) {
|
||||
ac->begin();
|
||||
ac->setMessageType(argoIrMessageType_t::IFEEL_TEMP_REPORT);
|
||||
ac->setSensorTemp(static_cast<uint8_t>(std::round(sensorTemp)));
|
||||
ac->send();
|
||||
}
|
||||
|
||||
/// Send an Argo A/C WREM-3 Config command.
|
||||
/// @param[in, out] ac A Ptr to an IRArgoAC_WREM3 object to use.
|
||||
/// @param[in] param The parameter ID.
|
||||
/// @param[in] value The parameter value.
|
||||
/// @param[in] safe If true, will only allow setting the below parameters
|
||||
/// in order to avoid accidentally setting a restricted
|
||||
/// vendor-specific param and breaking the A/C device
|
||||
/// @note Known parameters (P<xx>, where xx is the @c param)
|
||||
/// P05 - Temperature Scale (0-Celsius, 1-Fahrenheit)
|
||||
/// P06 - Transmission channel (0..3)
|
||||
/// P12 - ECO mode power input limit (30..99, default: 75)
|
||||
void IRac::argoWrem3_ConfigSet(IRArgoAC_WREM3 *ac, const uint8_t param,
|
||||
const uint8_t value, bool safe /*= true*/) {
|
||||
if (safe) {
|
||||
switch (param) {
|
||||
case 5: // temp. scale (note this is likely excess as not transmitted)
|
||||
if (value > 1) { return; /* invalid */ }
|
||||
break;
|
||||
case 6: // channel (note this is likely excess as not transmitted)
|
||||
if (value > 3) { return; /* invalid */ }
|
||||
break;
|
||||
case 12: // eco power limit
|
||||
if (value < 30 || value > 99) { return; /* invalid */ }
|
||||
break;
|
||||
default:
|
||||
return; /* invalid */
|
||||
}
|
||||
}
|
||||
ac->begin();
|
||||
ac->setMessageType(argoIrMessageType_t::CONFIG_PARAM_SET);
|
||||
ac->setConfigEntry(param, value);
|
||||
ac->send();
|
||||
}
|
||||
|
||||
/// Send an Argo A/C WREM-3 Delay timer command.
|
||||
/// @param[in, out] ac A Ptr to an IRArgoAC_WREM3 object to use.
|
||||
/// @param[in] on Whether the unit is currently on. The timer, upon elapse
|
||||
/// will toggle this state
|
||||
/// @param[in] currentTime currentTime in minutes, starting from 00:00
|
||||
/// @note For timer mode, this value is not really used much so can be zero.
|
||||
/// @param[in] delayMinutes Number of minutes after which the @c on state should
|
||||
/// be toggled
|
||||
/// @note Schedule timers are not exposed via this interface
|
||||
void IRac::argoWrem3_SetTimer(IRArgoAC_WREM3 *ac, bool on,
|
||||
const uint16_t currentTime, const uint16_t delayMinutes) {
|
||||
ac->begin();
|
||||
ac->setMessageType(argoIrMessageType_t::TIMER_COMMAND);
|
||||
ac->setPower(on);
|
||||
ac->setTimerType(argoTimerType_t::DELAY_TIMER);
|
||||
ac->setCurrentTimeMinutes(currentTime);
|
||||
// Note: Day of week is not set (no need)
|
||||
ac->setDelayTimerMinutes(delayMinutes);
|
||||
ac->send();
|
||||
}
|
||||
#endif // SEND_ARGO
|
||||
|
||||
#if SEND_BOSCH144
|
||||
|
@ -546,9 +703,12 @@ void IRac::carrier64(IRCarrierAc64 *ac,
|
|||
/// @param[in] on The power setting.
|
||||
/// @param[in] mode The operation mode setting.
|
||||
/// @param[in] degrees The temperature setting in degrees.
|
||||
/// @param[in] sensorTemp The room (iFeel) temperature sensor reading in degrees
|
||||
/// Celsius.
|
||||
/// @param[in] fan The speed setting for the fan.
|
||||
/// @param[in] swingv The vertical swing setting.
|
||||
/// @param[in] swingh The horizontal swing setting.
|
||||
/// @param[in] iFeel Whether to enable iFeel (remote temp) mode on the A/C unit.
|
||||
/// @param[in] turbo Run the device in turbo/powerful mode.
|
||||
/// @param[in] light Turn on the LED/Display mode.
|
||||
/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc
|
||||
|
@ -556,10 +716,11 @@ void IRac::carrier64(IRCarrierAc64 *ac,
|
|||
/// @note -1 is Off, >= 0 is on.
|
||||
void IRac::coolix(IRCoolixAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const float degrees, const float sensorTemp,
|
||||
const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
|
||||
const bool turbo, const bool light, const bool clean,
|
||||
const int16_t sleep) {
|
||||
const bool iFeel, const bool turbo, const bool light,
|
||||
const bool clean, const int16_t sleep) {
|
||||
ac->begin();
|
||||
ac->setPower(on);
|
||||
if (!on) {
|
||||
|
@ -576,6 +737,12 @@ void IRac::coolix(IRCoolixAC *ac,
|
|||
// No Clock setting available.
|
||||
// No Econo setting available.
|
||||
// No Quiet setting available.
|
||||
if (sensorTemp != kNoTempValue) {
|
||||
ac->setSensorTemp(static_cast<uint8_t>(std::round(sensorTemp)));
|
||||
} else {
|
||||
ac->clearSensorTemp();
|
||||
}
|
||||
ac->setZoneFollow(iFeel);
|
||||
ac->send(); // Send the state, which will also power on the unit.
|
||||
// The following are all options/settings that create their own special
|
||||
// messages. Often they only make sense to be sent after the unit is turned
|
||||
|
@ -940,13 +1107,16 @@ void IRac::delonghiac(IRDelonghiAc *ac,
|
|||
/// @param[in] on The power setting.
|
||||
/// @param[in] mode The operation mode setting.
|
||||
/// @param[in] degrees The temperature setting in degrees.
|
||||
/// @param[in] sensorTemp The room (iFeel) temperature sensor reading in degrees
|
||||
/// Celsius.
|
||||
/// @param[in] fan The speed setting for the fan.
|
||||
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
|
||||
/// @param[in] clock The time in Nr. of mins since midnight. < 0 is ignore.
|
||||
void IRac::ecoclim(IREcoclimAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const int16_t sleep, const int16_t clock) {
|
||||
const float degrees, const float sensorTemp,
|
||||
const stdAc::fanspeed_t fan, const int16_t sleep,
|
||||
const int16_t clock) {
|
||||
ac->begin();
|
||||
ac->setPower(on);
|
||||
uint8_t new_mode;
|
||||
|
@ -956,8 +1126,13 @@ void IRac::ecoclim(IREcoclimAc *ac,
|
|||
new_mode = ac->convertMode(mode); // Not Sleep, so use the supplied mode.
|
||||
ac->setMode(new_mode);
|
||||
ac->setTemp(degrees);
|
||||
ac->setSensorTemp(degrees); //< Set to the desired temp until we cab disable.
|
||||
ac->setFan(ac->convertFan(fan));
|
||||
if (sensorTemp != kNoTempValue) {
|
||||
ac->setSensorTemp(static_cast<uint8_t>(std::round(sensorTemp)));
|
||||
} else {
|
||||
ac->setSensorTemp(degrees); //< Set to the desired temp
|
||||
// until we can disable.
|
||||
}
|
||||
// No SwingV setting available
|
||||
// No SwingH setting available
|
||||
// No Quiet setting available.
|
||||
|
@ -979,22 +1154,28 @@ void IRac::ecoclim(IREcoclimAc *ac,
|
|||
/// @param[in] on The power setting.
|
||||
/// @param[in] mode The operation mode setting.
|
||||
/// @param[in] degrees The temperature setting in degrees.
|
||||
/// @param[in] sensorTemp The room (iFeel) temperature sensor reading in degrees
|
||||
/// Celsius.
|
||||
/// @param[in] fan The speed setting for the fan.
|
||||
/// @param[in] swingv The vertical swing setting.
|
||||
/// @param[in] swingh The horizontal swing setting.
|
||||
/// @param[in] iFeel Whether to enable iFeel (remote temp) mode on the A/C unit.
|
||||
/// @param[in] turbo Run the device in turbo/powerful mode.
|
||||
/// @param[in] lighttoggle Should we toggle the LED/Display?
|
||||
/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc
|
||||
void IRac::electra(IRElectraAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv,
|
||||
const stdAc::swingh_t swingh, const bool turbo,
|
||||
const bool lighttoggle, const bool clean) {
|
||||
const float degrees, const float sensorTemp,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const stdAc::swingh_t swingh, const bool iFeel,
|
||||
const bool turbo, const bool lighttoggle, const bool clean) {
|
||||
ac->begin();
|
||||
ac->setPower(on);
|
||||
ac->setMode(ac->convertMode(mode));
|
||||
ac->setTemp(degrees);
|
||||
if (sensorTemp != kNoTempValue) {
|
||||
ac->setSensorTemp(static_cast<uint8_t>(std::round(sensorTemp)));
|
||||
}
|
||||
ac->setFan(ac->convertFan(fan));
|
||||
ac->setSwingV(swingv != stdAc::swingv_t::kOff);
|
||||
ac->setSwingH(swingh != stdAc::swingh_t::kOff);
|
||||
|
@ -1007,6 +1188,7 @@ void IRac::electra(IRElectraAc *ac,
|
|||
// No Beep setting available.
|
||||
// No Sleep setting available.
|
||||
// No Clock setting available.
|
||||
ac->setIFeel(iFeel);
|
||||
ac->send();
|
||||
}
|
||||
#endif // SEND_ELECTRA_AC
|
||||
|
@ -1132,6 +1314,7 @@ void IRac::goodweather(IRGoodweatherAc *ac,
|
|||
/// @param[in] fan The speed setting for the fan.
|
||||
/// @param[in] swingv The vertical swing setting.
|
||||
/// @param[in] swingh The horizontal swing setting.
|
||||
/// @param[in] iFeel Whether to enable iFeel (remote temp) mode on the A/C unit.
|
||||
/// @param[in] turbo Run the device in turbo/powerful mode.
|
||||
/// @param[in] econo Toggle the device's economical mode.
|
||||
/// @param[in] light Turn on the LED/Display mode.
|
||||
|
@ -1141,8 +1324,8 @@ void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model,
|
|||
const bool on, const stdAc::opmode_t mode, const bool celsius,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
|
||||
const bool turbo, const bool econo, const bool light,
|
||||
const bool clean, const int16_t sleep) {
|
||||
const bool iFeel, const bool turbo, const bool econo,
|
||||
const bool light, const bool clean, const int16_t sleep) {
|
||||
ac->begin();
|
||||
ac->setModel(model);
|
||||
ac->setPower(on);
|
||||
|
@ -1152,6 +1335,7 @@ void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model,
|
|||
ac->setSwingVertical(swingv == stdAc::swingv_t::kAuto, // Set auto flag.
|
||||
ac->convertSwingV(swingv));
|
||||
ac->setSwingHorizontal(ac->convertSwingH(swingh));
|
||||
ac->setIFeel(iFeel);
|
||||
ac->setLight(light);
|
||||
ac->setTurbo(turbo);
|
||||
ac->setEcono(econo);
|
||||
|
@ -1661,8 +1845,11 @@ void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model,
|
|||
/// @param[in] mode The operation mode setting.
|
||||
/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit.
|
||||
/// @param[in] degrees The temperature setting in degrees.
|
||||
/// @param[in] sensorTemp The room (iFeel) temperature sensor reading
|
||||
/// in degrees.
|
||||
/// @param[in] fan The speed setting for the fan.
|
||||
/// @param[in] swingv The vertical swing setting.
|
||||
/// @param[in] iFeel Whether to enable iFeel (remote temp) mode on the A/C unit.
|
||||
/// @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.
|
||||
|
@ -1673,9 +1860,9 @@ void IRac::lg(IRLgAc *ac, const lg_ac_remote_model_t model,
|
|||
/// @note On Danby A/C units, swingv controls the Ion Filter instead.
|
||||
void IRac::midea(IRMideaAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const bool celsius,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv,
|
||||
const bool quiet, const bool quiet_prev,
|
||||
const float degrees, const float sensorTemp,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const bool iFeel, 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();
|
||||
|
@ -1683,6 +1870,10 @@ void IRac::midea(IRMideaAC *ac,
|
|||
ac->setMode(ac->convertMode(mode));
|
||||
ac->setUseCelsius(celsius);
|
||||
ac->setTemp(degrees, celsius);
|
||||
if (sensorTemp != kNoTempValue) {
|
||||
ac->setSensorTemp(sensorTemp, celsius);
|
||||
}
|
||||
ac->setEnableSensorTemp(iFeel);
|
||||
ac->setFan(ac->convertFan(fan));
|
||||
ac->setSwingVToggle(swingv != stdAc::swingv_t::kOff);
|
||||
// No Horizontal swing setting available.
|
||||
|
@ -2080,19 +2271,29 @@ void IRac::samsung(IRSamsungAc *ac,
|
|||
/// @param[in] on The power setting.
|
||||
/// @param[in] mode The operation mode setting.
|
||||
/// @param[in] degrees The temperature setting in degrees.
|
||||
/// @param[in] sensorTemp The room (iFeel) temperature sensor reading in degrees
|
||||
/// Celsius.
|
||||
/// @param[in] fan The speed setting for the fan.
|
||||
/// @param[in] swingv The vertical swing setting.
|
||||
/// @param[in] iFeel Whether to enable iFeel (remote temp) mode on the A/C unit.
|
||||
/// @param[in] beep Enable/Disable beeps when receiving IR messages.
|
||||
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
|
||||
void IRac::sanyo(IRSanyoAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const bool beep,
|
||||
const int16_t sleep) {
|
||||
const float degrees, const float sensorTemp,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const bool iFeel, const bool beep, const int16_t sleep) {
|
||||
ac->begin();
|
||||
ac->setPower(on);
|
||||
ac->setMode(ac->convertMode(mode));
|
||||
ac->setTemp(degrees);
|
||||
if (sensorTemp != kNoTempValue) {
|
||||
ac->setSensorTemp(static_cast<uint8_t>(std::round(sensorTemp)));
|
||||
} else {
|
||||
ac->setSensorTemp(degrees); // Set the sensor temp to the desired
|
||||
// (normal) temp.
|
||||
}
|
||||
ac->setSensor(!iFeel);
|
||||
ac->setFan(ac->convertFan(fan));
|
||||
ac->setSwingV(ac->convertSwingV(swingv));
|
||||
// No Horizontal swing setting available.
|
||||
|
@ -2105,10 +2306,6 @@ void IRac::sanyo(IRSanyoAc *ac,
|
|||
ac->setBeep(beep);
|
||||
ac->setSleep(sleep >= 0); // Sleep is either on/off, so convert to boolean.
|
||||
// No Clock setting available.
|
||||
|
||||
// Extra
|
||||
ac->setSensor(true); // Set the A/C to use the temp sensor in the Unit/Wall.
|
||||
ac->setSensorTemp(degrees); // Set the sensor temp to the desired temp.
|
||||
ac->send();
|
||||
}
|
||||
#endif // SEND_SANYO_AC
|
||||
|
@ -2801,6 +2998,11 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
|||
// Convert the temp from Fahrenheit to Celsius if we are not in Celsius mode.
|
||||
float degC __attribute__((unused)) =
|
||||
desired.celsius ? desired.degrees : fahrenheitToCelsius(desired.degrees);
|
||||
// Convert the sensorTemp from Fahrenheit to Celsius if we are not in Celsius
|
||||
// mode.
|
||||
float sensorTempC __attribute__((unused)) =
|
||||
desired.sensorTemperature ? desired.sensorTemperature
|
||||
: fahrenheitToCelsius(desired.sensorTemperature);
|
||||
// special `state_t` that is required to be sent based on that.
|
||||
stdAc::state_t send = this->handleToggles(this->cleanState(desired), prev);
|
||||
// Some protocols expect a previous state for power.
|
||||
|
@ -2850,9 +3052,36 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
|||
#if SEND_ARGO
|
||||
case ARGO:
|
||||
{
|
||||
IRArgoAC ac(_pin, _inverted, _modulation);
|
||||
argo(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
|
||||
send.turbo, send.sleep);
|
||||
if (send.model == argo_ac_remote_model_t::SAC_WREM3) {
|
||||
IRArgoAC_WREM3 ac(_pin, _inverted, _modulation);
|
||||
switch (send.command) {
|
||||
case stdAc::ac_command_t::kSensorTempReport:
|
||||
argoWrem3_iFeelReport(&ac, sensorTempC);
|
||||
break;
|
||||
case stdAc::ac_command_t::kConfigCommand:
|
||||
/// @warning: this is ABUSING current **common** parameters:
|
||||
/// @c clock and @c sleep as config key and value
|
||||
/// Hence, value pre-validation is performed (safe-mode)
|
||||
/// to avoid accidental device misconfiguration
|
||||
argoWrem3_ConfigSet(&ac, send.clock, send.sleep, true);
|
||||
break;
|
||||
case stdAc::ac_command_t::kTimerCommand:
|
||||
argoWrem3_SetTimer(&ac, send.power, send.clock, send.sleep);
|
||||
break;
|
||||
case stdAc::ac_command_t::kControlCommand:
|
||||
default:
|
||||
argoWrem3_ACCommand(&ac, send.power, send.mode, degC, sensorTempC,
|
||||
send.fanspeed, send.swingv, send.iFeel, send.quiet, send.econo,
|
||||
send.turbo, send.filter, send.light);
|
||||
break;
|
||||
}
|
||||
OUTPUT_DECODE_RESULTS_FOR_UT(ac);
|
||||
} else {
|
||||
IRArgoAC ac(_pin, _inverted, _modulation);
|
||||
argo(&ac, send.power, send.mode, degC, sensorTempC, send.fanspeed,
|
||||
send.swingv, send.iFeel, send.turbo, send.sleep);
|
||||
OUTPUT_DECODE_RESULTS_FOR_UT(ac);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif // SEND_ARGO
|
||||
|
@ -2877,8 +3106,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
|||
case COOLIX:
|
||||
{
|
||||
IRCoolixAC ac(_pin, _inverted, _modulation);
|
||||
coolix(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
|
||||
send.swingh, send.turbo, send.light, send.clean, send.sleep);
|
||||
coolix(&ac, send.power, send.mode, degC, sensorTempC, send.fanspeed,
|
||||
send.swingv, send.swingh, send.iFeel, send.turbo, send.light,
|
||||
send.clean, send.sleep);
|
||||
break;
|
||||
}
|
||||
#endif // SEND_COOLIX
|
||||
|
@ -2976,7 +3206,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
|||
case ECOCLIM:
|
||||
{
|
||||
IREcoclimAc ac(_pin, _inverted, _modulation);
|
||||
ecoclim(&ac, send.power, send.mode, degC, send.fanspeed, send.clock);
|
||||
ecoclim(&ac, send.power, send.mode, degC, sensorTempC, send.fanspeed,
|
||||
send.iFeel, send.clock);
|
||||
break;
|
||||
}
|
||||
#endif // SEND_ECOCLIM
|
||||
|
@ -2984,8 +3215,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
|||
case ELECTRA_AC:
|
||||
{
|
||||
IRElectraAc ac(_pin, _inverted, _modulation);
|
||||
electra(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
|
||||
send.swingh, send.turbo, send.light, send.clean);
|
||||
electra(&ac, send.power, send.mode, degC, sensorTempC, send.fanspeed,
|
||||
send.swingv, send.swingh, send.iFeel, send.turbo, send.light,
|
||||
send.clean);
|
||||
break;
|
||||
}
|
||||
#endif // SEND_ELECTRA_AC
|
||||
|
@ -3153,8 +3385,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
|||
{
|
||||
IRMideaAC ac(_pin, _inverted, _modulation);
|
||||
midea(&ac, send.power, send.mode, send.celsius, send.degrees,
|
||||
send.fanspeed, send.swingv, send.quiet, prev_quiet, send.turbo,
|
||||
send.econo, send.light, send.sleep);
|
||||
send.sensorTemperature, send.fanspeed, send.swingv, send.iFeel,
|
||||
send.quiet, prev_quiet, send.turbo, send.econo, send.light,
|
||||
send.clean, send.sleep);
|
||||
break;
|
||||
}
|
||||
#endif // SEND_MIDEA
|
||||
|
@ -3263,8 +3496,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
|
|||
case SANYO_AC:
|
||||
{
|
||||
IRSanyoAc ac(_pin, _inverted, _modulation);
|
||||
sanyo(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
|
||||
send.beep, send.sleep);
|
||||
sanyo(&ac, send.power, send.mode, degC, sensorTempC, send.fanspeed,
|
||||
send.swingv, send.iFeel, send.beep, send.sleep);
|
||||
break;
|
||||
}
|
||||
#endif // SEND_SANYO_AC
|
||||
|
@ -3421,7 +3654,9 @@ bool IRac::cmpStates(const stdAc::state_t a, const stdAc::state_t b) {
|
|||
a.fanspeed != b.fanspeed || a.swingv != b.swingv ||
|
||||
a.swingh != b.swingh || a.quiet != b.quiet || a.turbo != b.turbo ||
|
||||
a.econo != b.econo || a.light != b.light || a.filter != b.filter ||
|
||||
a.clean != b.clean || a.beep != b.beep || a.sleep != b.sleep;
|
||||
a.clean != b.clean || a.beep != b.beep || a.sleep != b.sleep ||
|
||||
a.command != b.command || a.sensorTemperature != b.sensorTemperature ||
|
||||
a.iFeel != b.iFeel;
|
||||
}
|
||||
|
||||
/// Check if the internal state has changed from what was previously sent.
|
||||
|
@ -3429,6 +3664,26 @@ bool IRac::cmpStates(const stdAc::state_t a, const stdAc::state_t b) {
|
|||
/// @return True if it has changed, False if not.
|
||||
bool IRac::hasStateChanged(void) { return cmpStates(next, _prev); }
|
||||
|
||||
/// Convert the supplied str into the appropriate enum.
|
||||
/// @param[in] str A Ptr to a C-style string to be converted.
|
||||
/// @param[in] def The enum to return if no conversion was possible.
|
||||
/// @return The equivalent enum.
|
||||
stdAc::ac_command_t IRac::strToCommandType(const char *str,
|
||||
const stdAc::ac_command_t def) {
|
||||
if (!STRCASECMP(str, kControlCommandStr))
|
||||
return stdAc::ac_command_t::kControlCommand;
|
||||
else if (!STRCASECMP(str, kIFeelReportStr) ||
|
||||
!STRCASECMP(str, kIFeelStr))
|
||||
return stdAc::ac_command_t::kSensorTempReport;
|
||||
else if (!STRCASECMP(str, kSetTimerCommandStr) ||
|
||||
!STRCASECMP(str, kTimerStr))
|
||||
return stdAc::ac_command_t::kTimerCommand;
|
||||
else if (!STRCASECMP(str, kConfigCommandStr))
|
||||
return stdAc::ac_command_t::kConfigCommand;
|
||||
else
|
||||
return def;
|
||||
}
|
||||
|
||||
/// Convert the supplied str into the appropriate enum.
|
||||
/// @param[in] str A Ptr to a C-style string to be converted.
|
||||
/// @param[in] def The enum to return if no conversion was possible.
|
||||
|
@ -3492,6 +3747,8 @@ stdAc::fanspeed_t IRac::strToFanspeed(const char *str,
|
|||
!STRCASECMP(str, kMaximumStr) ||
|
||||
!STRCASECMP(str, kHighestStr))
|
||||
return stdAc::fanspeed_t::kMax;
|
||||
else if (!STRCASECMP(str, kMedHighStr))
|
||||
return stdAc::fanspeed_t::kMediumHigh;
|
||||
else
|
||||
return def;
|
||||
}
|
||||
|
@ -3524,6 +3781,8 @@ stdAc::swingv_t IRac::strToSwingV(const char *str,
|
|||
!STRCASECMP(str, kMediumStr) ||
|
||||
!STRCASECMP(str, kCentreStr))
|
||||
return stdAc::swingv_t::kMiddle;
|
||||
else if (!STRCASECMP(str, kUpperMiddleStr))
|
||||
return stdAc::swingv_t::kUpperMiddle;
|
||||
else if (!STRCASECMP(str, kHighStr) ||
|
||||
!STRCASECMP(str, kHiStr))
|
||||
return stdAc::swingv_t::kHigh;
|
||||
|
@ -3666,6 +3925,11 @@ int16_t IRac::strToModel(const char *str, const int16_t def) {
|
|||
return whirlpool_ac_remote_model_t::DG11J13A;
|
||||
} else if (!STRCASECMP(str, kDg11j191Str)) {
|
||||
return whirlpool_ac_remote_model_t::DG11J191;
|
||||
// Argo A/C models
|
||||
} else if (!STRCASECMP(str, kArgoWrem2Str)) {
|
||||
return argo_ac_remote_model_t::SAC_WREM2;
|
||||
} else if (!STRCASECMP(str, kArgoWrem3Str)) {
|
||||
return argo_ac_remote_model_t::SAC_WREM3;
|
||||
} else {
|
||||
int16_t number = atoi(str);
|
||||
if (number > 0)
|
||||
|
@ -3701,6 +3965,19 @@ String IRac::boolToString(const bool value) {
|
|||
return value ? kOnStr : kOffStr;
|
||||
}
|
||||
|
||||
/// Convert the supplied operation mode into the appropriate String.
|
||||
/// @param[in] cmdType The enum to be converted.
|
||||
/// @return The equivalent String for the locale.
|
||||
String IRac::commandTypeToString(const stdAc::ac_command_t cmdType) {
|
||||
switch (cmdType) {
|
||||
case stdAc::ac_command_t::kControlCommand: return kControlCommandStr;
|
||||
case stdAc::ac_command_t::kSensorTempReport: return kIFeelReportStr;
|
||||
case stdAc::ac_command_t::kTimerCommand: return kSetTimerCommandStr;
|
||||
case stdAc::ac_command_t::kConfigCommand: return kConfigCommandStr;
|
||||
default: return kUnknownStr;
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the supplied operation mode into the appropriate String.
|
||||
/// @param[in] mode The enum to be converted.
|
||||
/// @param[in] ha A flag to indicate we want GoogleHome/HomeAssistant output.
|
||||
|
@ -3722,13 +3999,14 @@ String IRac::opmodeToString(const stdAc::opmode_t mode, const bool ha) {
|
|||
/// @return The equivalent String for the locale.
|
||||
String IRac::fanspeedToString(const stdAc::fanspeed_t speed) {
|
||||
switch (speed) {
|
||||
case stdAc::fanspeed_t::kAuto: return kAutoStr;
|
||||
case stdAc::fanspeed_t::kMax: return kMaxStr;
|
||||
case stdAc::fanspeed_t::kHigh: return kHighStr;
|
||||
case stdAc::fanspeed_t::kMedium: return kMediumStr;
|
||||
case stdAc::fanspeed_t::kLow: return kLowStr;
|
||||
case stdAc::fanspeed_t::kMin: return kMinStr;
|
||||
default: return kUnknownStr;
|
||||
case stdAc::fanspeed_t::kAuto: return kAutoStr;
|
||||
case stdAc::fanspeed_t::kMax: return kMaxStr;
|
||||
case stdAc::fanspeed_t::kHigh: return kHighStr;
|
||||
case stdAc::fanspeed_t::kMedium: return kMediumStr;
|
||||
case stdAc::fanspeed_t::kMediumHigh: return kMedHighStr;
|
||||
case stdAc::fanspeed_t::kLow: return kLowStr;
|
||||
case stdAc::fanspeed_t::kMin: return kMinStr;
|
||||
default: return kUnknownStr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3737,14 +4015,15 @@ String IRac::fanspeedToString(const stdAc::fanspeed_t speed) {
|
|||
/// @return The equivalent String for the locale.
|
||||
String IRac::swingvToString(const stdAc::swingv_t swingv) {
|
||||
switch (swingv) {
|
||||
case stdAc::swingv_t::kOff: return kOffStr;
|
||||
case stdAc::swingv_t::kAuto: return kAutoStr;
|
||||
case stdAc::swingv_t::kHighest: return kHighestStr;
|
||||
case stdAc::swingv_t::kHigh: return kHighStr;
|
||||
case stdAc::swingv_t::kMiddle: return kMiddleStr;
|
||||
case stdAc::swingv_t::kLow: return kLowStr;
|
||||
case stdAc::swingv_t::kLowest: return kLowestStr;
|
||||
default: return kUnknownStr;
|
||||
case stdAc::swingv_t::kOff: return kOffStr;
|
||||
case stdAc::swingv_t::kAuto: return kAutoStr;
|
||||
case stdAc::swingv_t::kHighest: return kHighestStr;
|
||||
case stdAc::swingv_t::kHigh: return kHighStr;
|
||||
case stdAc::swingv_t::kMiddle: return kMiddleStr;
|
||||
case stdAc::swingv_t::kUpperMiddle: return kUpperMiddleStr;
|
||||
case stdAc::swingv_t::kLow: return kLowStr;
|
||||
case stdAc::swingv_t::kLowest: return kLowestStr;
|
||||
default: return kUnknownStr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3796,8 +4075,14 @@ namespace IRAcUtils {
|
|||
#endif // DECODE_AMCOR
|
||||
#if DECODE_ARGO
|
||||
case decode_type_t::ARGO: {
|
||||
if (IRArgoAC_WREM3::isValidWrem3Message(result->state, result->bits,
|
||||
true)) {
|
||||
IRArgoAC_WREM3 ac(kGpioUnused);
|
||||
ac.setRaw(result->state, result->bits / 8);
|
||||
return ac.toString();
|
||||
}
|
||||
IRArgoAC ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
ac.setRaw(result->state, result->bits / 8);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_ARGO
|
||||
|
@ -4211,6 +4496,13 @@ namespace IRAcUtils {
|
|||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_WHIRLPOOL_AC
|
||||
#if DECODE_YORK
|
||||
case decode_type_t::YORK: {
|
||||
IRYorkAc ac(kGpioUnused);
|
||||
ac.setRaw(result->state);
|
||||
return ac.toString();
|
||||
}
|
||||
#endif // DECODE_YORK
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
@ -4258,9 +4550,24 @@ namespace IRAcUtils {
|
|||
#endif // DECODE_AMCOR
|
||||
#if DECODE_ARGO
|
||||
case decode_type_t::ARGO: {
|
||||
IRArgoAC ac(kGpioUnused);
|
||||
ac.setRaw(decode->state);
|
||||
*result = ac.toCommon();
|
||||
const uint16_t length = decode->bits / 8;
|
||||
if (IRArgoAC_WREM3::isValidWrem3Message(decode->state,
|
||||
decode->bits, true)) {
|
||||
IRArgoAC_WREM3 ac(kGpioUnused);
|
||||
ac.setRaw(decode->state, length);
|
||||
*result = ac.toCommon();
|
||||
} else {
|
||||
IRArgoAC ac(kGpioUnused);
|
||||
switch (length) {
|
||||
case kArgoStateLength:
|
||||
case kArgoShortStateLength:
|
||||
ac.setRaw(decode->state, length);
|
||||
*result = ac.toCommon();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif // DECODE_ARGO
|
||||
|
@ -4732,6 +5039,14 @@ namespace IRAcUtils {
|
|||
break;
|
||||
}
|
||||
#endif // DECODE_WHIRLPOOL_AC
|
||||
#if DECODE_YORK
|
||||
case decode_type_t::YORK: {
|
||||
IRYorkAc ac(kGpioUnused);
|
||||
ac.setRaw(decode->state);
|
||||
*result = ac.toCommon(prev);
|
||||
break;
|
||||
}
|
||||
#endif // DECODE_YORK
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#ifndef UNIT_TEST
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <memory>
|
||||
#endif
|
||||
#include "IRremoteESP8266.h"
|
||||
#include "ir_Airton.h"
|
||||
|
@ -47,6 +49,7 @@
|
|||
#include "ir_Vestel.h"
|
||||
#include "ir_Voltas.h"
|
||||
#include "ir_Whirlpool.h"
|
||||
#include "ir_York.h"
|
||||
|
||||
// Constants
|
||||
const int8_t kGpioUnused = -1; ///< A placeholder for not using an actual GPIO.
|
||||
|
@ -84,6 +87,8 @@ class IRac {
|
|||
static bool cmpStates(const stdAc::state_t a, const stdAc::state_t b);
|
||||
static bool strToBool(const char *str, const bool def = false);
|
||||
static int16_t strToModel(const char *str, const int16_t def = -1);
|
||||
static stdAc::ac_command_t strToCommandType(const char *str,
|
||||
const stdAc::ac_command_t def = stdAc::ac_command_t::kControlCommand);
|
||||
static stdAc::opmode_t strToOpmode(
|
||||
const char *str, const stdAc::opmode_t def = stdAc::opmode_t::kAuto);
|
||||
static stdAc::fanspeed_t strToFanspeed(
|
||||
|
@ -94,6 +99,7 @@ class IRac {
|
|||
static stdAc::swingh_t strToSwingH(
|
||||
const char *str, const stdAc::swingh_t def = stdAc::swingh_t::kOff);
|
||||
static String boolToString(const bool value);
|
||||
static String commandTypeToString(const stdAc::ac_command_t cmdType);
|
||||
static String opmodeToString(const stdAc::opmode_t mode,
|
||||
const bool ha = false);
|
||||
static String fanspeedToString(const stdAc::fanspeed_t speed);
|
||||
|
@ -103,10 +109,17 @@ class IRac {
|
|||
stdAc::state_t getStatePrev(void);
|
||||
bool hasStateChanged(void);
|
||||
stdAc::state_t next; ///< The state we want the device to be in after we send
|
||||
#ifndef UNIT_TEST
|
||||
#ifdef UNIT_TEST
|
||||
/// @cond IGNORE
|
||||
/// UT-specific
|
||||
/// See @c OUTPUT_DECODE_RESULTS_FOR_UT macro description in IRac.cpp
|
||||
std::shared_ptr<IRrecv> _utReceiver = nullptr;
|
||||
std::unique_ptr<decode_results> _lastDecodeResults = nullptr;
|
||||
/// @endcond
|
||||
#else
|
||||
|
||||
private:
|
||||
#endif
|
||||
#endif // UNIT_TEST
|
||||
uint16_t _pin; ///< The GPIO to use to transmit messages from.
|
||||
bool _inverted; ///< IR LED is lit when GPIO is LOW (true) or HIGH (false)?
|
||||
bool _modulation; ///< Is frequency modulation to be used?
|
||||
|
@ -132,15 +145,26 @@ class IRac {
|
|||
#if SEND_ARGO
|
||||
void argo(IRArgoAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const bool turbo, const int16_t sleep = -1);
|
||||
const float sensorTemp, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const bool iFeel, const bool turbo,
|
||||
const int16_t sleep = -1);
|
||||
void argoWrem3_ACCommand(IRArgoAC_WREM3 *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
const float sensorTemp, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const bool iFeel, const bool night,
|
||||
const bool econo, const bool turbo, const bool filter, const bool light);
|
||||
void argoWrem3_iFeelReport(IRArgoAC_WREM3 *ac, const float sensorTemp);
|
||||
void argoWrem3_ConfigSet(IRArgoAC_WREM3 *ac, const uint8_t param,
|
||||
const uint8_t value, bool safe = true);
|
||||
void argoWrem3_SetTimer(IRArgoAC_WREM3 *ac, bool on,
|
||||
const uint16_t currentTime, const uint16_t delayMinutes);
|
||||
#endif // SEND_ARGO
|
||||
#if SEND_BOSCH144
|
||||
void bosch144(IRBosch144AC *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
const stdAc::fanspeed_t fan,
|
||||
const bool quiet);
|
||||
#endif // SEND_COOLIX
|
||||
#endif // SEND_BOSCH144
|
||||
#if SEND_CARRIER_AC64
|
||||
void carrier64(IRCarrierAc64 *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
|
@ -150,10 +174,10 @@ void carrier64(IRCarrierAc64 *ac,
|
|||
#if SEND_COOLIX
|
||||
void coolix(IRCoolixAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
const stdAc::fanspeed_t fan,
|
||||
const float sensorTemp, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
|
||||
const bool turbo, const bool light, const bool clean,
|
||||
const int16_t sleep = -1);
|
||||
const bool iFeel, const bool turbo, const bool light,
|
||||
const bool clean, const int16_t sleep = -1);
|
||||
#endif // SEND_COOLIX
|
||||
#if SEND_CORONA_AC
|
||||
void corona(IRCoronaAc *ac,
|
||||
|
@ -231,15 +255,16 @@ void daikin216(IRDaikin216 *ac,
|
|||
#if SEND_ECOCLIM
|
||||
void ecoclim(IREcoclimAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const int16_t sleep = -1, const int16_t clock = -1);
|
||||
const float degrees, const float sensorTemp,
|
||||
const stdAc::fanspeed_t fan, const int16_t sleep = -1,
|
||||
const int16_t clock = -1);
|
||||
#endif // SEND_ECOCLIM
|
||||
#if SEND_ELECTRA_AC
|
||||
void electra(IRElectraAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv,
|
||||
const stdAc::swingh_t swingh, const bool turbo,
|
||||
const float degrees, const float sensorTemp,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const stdAc::swingh_t swingh, const bool iFeel, const bool turbo,
|
||||
const bool lighttoggle, const bool clean);
|
||||
#endif // SEND_ELECTRA_AC
|
||||
#if SEND_FUJITSU_AC
|
||||
|
@ -265,8 +290,8 @@ void electra(IRElectraAc *ac,
|
|||
const bool on, const stdAc::opmode_t mode, const bool celsius,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
|
||||
const bool turbo, const bool econo, const bool light,
|
||||
const bool clean, const int16_t sleep = -1);
|
||||
const bool iFeel, const bool turbo, const bool econo,
|
||||
const bool light, const bool clean, const int16_t sleep = -1);
|
||||
#endif // SEND_GREE
|
||||
#if SEND_HAIER_AC
|
||||
void haier(IRHaierAC *ac,
|
||||
|
@ -363,11 +388,11 @@ void electra(IRElectraAc *ac,
|
|||
#if SEND_MIDEA
|
||||
void midea(IRMideaAC *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const bool celsius,
|
||||
const float degrees, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv,
|
||||
const bool quiet, const bool quiet_prev, const bool turbo,
|
||||
const bool econo, const bool light, const bool clean,
|
||||
const int16_t sleep = -1);
|
||||
const float degrees, const float sensorTemp,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const bool iFeel, 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
|
||||
#if SEND_MIRAGE
|
||||
void mirage(IRMirageAc *ac, const stdAc::state_t state);
|
||||
|
@ -451,8 +476,9 @@ void electra(IRElectraAc *ac,
|
|||
#if SEND_SANYO_AC
|
||||
void sanyo(IRSanyoAc *ac,
|
||||
const bool on, const stdAc::opmode_t mode, const float degrees,
|
||||
const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
|
||||
const bool beep, const int16_t sleep = -1);
|
||||
const float sensorTemp, const stdAc::fanspeed_t fan,
|
||||
const stdAc::swingv_t swingv, const bool iFeel, const bool beep,
|
||||
const int16_t sleep = -1);
|
||||
#endif // SEND_SANYO_AC
|
||||
#if SEND_SANYO_AC88
|
||||
void sanyo88(IRSanyoAc88 *ac,
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#if !VA_OPT_SUPPORTED
|
||||
// #pragma message("Compiler without __VA_OPT__ support")
|
||||
#define COND(cond, a, b) a
|
||||
#else
|
||||
#else // !VA_OPT_SUPPORTED
|
||||
#define NOTHING
|
||||
#define EXPAND(...) __VA_ARGS__
|
||||
#define STUFF_P(a, ...) __VA_OPT__(a)
|
||||
|
@ -44,7 +44,7 @@
|
|||
#define NEGATE(a) VA_TEST(a, a)
|
||||
#define COND_P(cond, a, b) STUFF(a, cond)STUFF(b, NEGATE(cond))
|
||||
#define COND(cond, a, b) EXPAND(COND_P(cond, a, b))
|
||||
#endif
|
||||
#endif // !VA_OPT_SUPPORTED
|
||||
/// @endcond
|
||||
/**
|
||||
* end of COND() set of macros
|
||||
|
|
|
@ -399,6 +399,7 @@ void IRrecv::disableIRIn(void) {
|
|||
#endif // ESP8266
|
||||
#if defined(ESP32)
|
||||
timerAlarmDisable(timer);
|
||||
timerDetachInterrupt(timer);
|
||||
timerEnd(timer);
|
||||
#endif // ESP32
|
||||
detachInterrupt(params.recvpin);
|
||||
|
@ -709,9 +710,12 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
|
|||
return true;
|
||||
#endif
|
||||
#if DECODE_PANASONIC
|
||||
DPRINTLN("Attempting Panasonic decode");
|
||||
DPRINTLN("Attempting Panasonic (48-bit) decode");
|
||||
if (decodePanasonic(results, offset)) return true;
|
||||
#endif
|
||||
DPRINTLN("Attempting Panasonic (40-bit) decode");
|
||||
if (decodePanasonic(results, offset, kPanasonic40Bits, true,
|
||||
kPanasonic40Manufacturer)) return true;
|
||||
#endif // DECODE_PANASONIC
|
||||
#if DECODE_LG
|
||||
DPRINTLN("Attempting LG (28-bit) decode");
|
||||
if (decodeLG(results, offset, kLgBits, true)) return true;
|
||||
|
@ -951,8 +955,21 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
|
|||
return true;
|
||||
#endif
|
||||
#if DECODE_ARGO
|
||||
DPRINTLN("Attempting Argo decode");
|
||||
if (decodeArgo(results, offset)) return true;
|
||||
DPRINTLN("Attempting Argo WREM3 decode (AC Control)");
|
||||
if (decodeArgoWREM3(results, offset, kArgo3AcControlStateLength * 8, true))
|
||||
return true;
|
||||
DPRINTLN("Attempting Argo WREM3 decode (iFeel report)");
|
||||
if (decodeArgoWREM3(results, offset, kArgo3iFeelReportStateLength * 8, true))
|
||||
return true;
|
||||
DPRINTLN("Attempting Argo WREM3 decode (Config)");
|
||||
if (decodeArgoWREM3(results, offset, kArgo3ConfigStateLength * 8, true))
|
||||
return true;
|
||||
DPRINTLN("Attempting Argo WREM3 decode (Timer)");
|
||||
if (decodeArgoWREM3(results, offset, kArgo3TimerStateLength * 8, true))
|
||||
return true;
|
||||
DPRINTLN("Attempting Argo WREM2 decode");
|
||||
if (decodeArgo(results, offset, kArgoBits) ||
|
||||
decodeArgo(results, offset, kArgoShortBits, false)) return true;
|
||||
#endif // DECODE_ARGO
|
||||
#if DECODE_SHARP_AC
|
||||
DPRINTLN("Attempting SHARP_AC decode");
|
||||
|
@ -1160,6 +1177,22 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
|
|||
DPRINTLN("Attempting Daikin 312-bit decode");
|
||||
if (decodeDaikin312(results, offset)) return true;
|
||||
#endif // DECODE_DAIKIN312
|
||||
#if DECODE_GORENJE
|
||||
DPRINTLN("Attempting GORENJE decode");
|
||||
if (decodeGorenje(results, offset)) return true;
|
||||
#endif // DECODE_GORENJE
|
||||
#if DECODE_WOWWEE
|
||||
DPRINTLN("Attempting WOWWEE decode");
|
||||
if (decodeWowwee(results, offset)) return true;
|
||||
#endif // DECODE_WOWWEE
|
||||
#if DECODE_CARRIER_AC84
|
||||
DPRINTLN("Attempting Carrier A/C 84-bit decode");
|
||||
if (decodeCarrierAC84(results, offset)) return true;
|
||||
#endif // DECODE_CARRIER_AC84
|
||||
#if DECODE_YORK
|
||||
DPRINTLN("Attempting York decode");
|
||||
if (decodeYork(results, offset, kYorkBits)) return true;
|
||||
#endif // DECODE_YORK
|
||||
// Typically new protocols are added above this line.
|
||||
}
|
||||
#if DECODE_HASH
|
||||
|
|
|
@ -294,6 +294,9 @@ class IRrecv {
|
|||
#if DECODE_ARGO
|
||||
bool decodeArgo(decode_results *results, uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kArgoBits, const bool strict = true);
|
||||
bool decodeArgoWREM3(decode_results *results, uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kArgo3AcControlStateLength * 8,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_ARGO
|
||||
#if DECODE_ARRIS
|
||||
bool decodeArris(decode_results *results, uint16_t offset = kStartOffset,
|
||||
|
@ -580,6 +583,12 @@ class IRrecv {
|
|||
const uint16_t nbits = kCarrierAc40Bits,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_CARRIER_AC40
|
||||
#if DECODE_CARRIER_AC84
|
||||
bool decodeCarrierAC84(decode_results *results,
|
||||
uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kCarrierAc84Bits,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_CARRIER_AC84
|
||||
#if DECODE_CARRIER_AC64
|
||||
bool decodeCarrierAC64(decode_results *results,
|
||||
uint16_t offset = kStartOffset,
|
||||
|
@ -598,6 +607,11 @@ class IRrecv {
|
|||
const uint16_t nbits = kGoodweatherBits,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_GOODWEATHER
|
||||
#if DECODE_GORENJE
|
||||
bool decodeGorenje(decode_results *results, uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kGorenjeBits,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_GORENJE
|
||||
#if DECODE_GREE
|
||||
bool decodeGree(decode_results *results, uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kGreeBits,
|
||||
|
@ -857,6 +871,18 @@ class IRrecv {
|
|||
const uint16_t nbits = kBosch144Bits,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_BOSCH144
|
||||
#if DECODE_WOWWEE
|
||||
bool decodeWowwee(decode_results *results,
|
||||
uint16_t offset = kStartOffset,
|
||||
const uint16_t nbits = kWowweeBits,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_WOWWEE
|
||||
#if DECODE_YORK
|
||||
bool decodeYork(decode_results *results,
|
||||
uint16_t kStartOffset,
|
||||
const uint16_t kYorkBits,
|
||||
const bool strict = true);
|
||||
#endif // DECODE_YORK
|
||||
};
|
||||
|
||||
#endif // IRRECV_H_
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
// Minor version number (x.X.x)
|
||||
#define _IRREMOTEESP8266_VERSION_MINOR 8
|
||||
// Patch version number (x.x.X)
|
||||
#define _IRREMOTEESP8266_VERSION_PATCH 4
|
||||
#define _IRREMOTEESP8266_VERSION_PATCH 5
|
||||
// Macro to convert version info into an integer
|
||||
#define _IRREMOTEESP8266_VERSION_VAL(major, minor, patch) \
|
||||
(((major) << 16) | ((minor) << 8) | (patch))
|
||||
|
@ -924,6 +924,34 @@
|
|||
#define SEND_DAIKIN312 _IR_ENABLE_DEFAULT_
|
||||
#endif // SEND_DAIKIN312
|
||||
|
||||
#ifndef DECODE_GORENJE
|
||||
#define DECODE_GORENJE _IR_ENABLE_DEFAULT_
|
||||
#endif // DECODE_GORENJE
|
||||
#ifndef SEND_GORENJE
|
||||
#define SEND_GORENJE _IR_ENABLE_DEFAULT_
|
||||
#endif // SEND_GORENJE
|
||||
|
||||
#ifndef DECODE_WOWWEE
|
||||
#define DECODE_WOWWEE _IR_ENABLE_DEFAULT_
|
||||
#endif // DECODE_WOWWEE
|
||||
#ifndef SEND_WOWWEE
|
||||
#define SEND_WOWWEE _IR_ENABLE_DEFAULT_
|
||||
#endif // SEND_WOWWEE
|
||||
|
||||
#ifndef DECODE_CARRIER_AC84
|
||||
#define DECODE_CARRIER_AC84 _IR_ENABLE_DEFAULT_
|
||||
#endif // DECODE_CARRIER_AC84
|
||||
#ifndef SEND_CARRIER_AC84
|
||||
#define SEND_CARRIER_AC84 _IR_ENABLE_DEFAULT_
|
||||
#endif // SEND_CARRIER_AC84
|
||||
|
||||
#ifndef DECODE_YORK
|
||||
#define DECODE_YORK _IR_ENABLE_DEFAULT_
|
||||
#endif // DECODE_YORK
|
||||
#ifndef SEND_YORK
|
||||
#define SEND_YORK _IR_ENABLE_DEFAULT_
|
||||
#endif // SEND_YORK
|
||||
|
||||
#if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \
|
||||
DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \
|
||||
DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \
|
||||
|
@ -942,6 +970,7 @@
|
|||
DECODE_KELON168 || DECODE_HITACHI_AC296 || DECODE_CARRIER_AC128 || \
|
||||
DECODE_DAIKIN200 || DECODE_HAIER_AC160 || DECODE_TCL96AC || \
|
||||
DECODE_BOSCH144 || DECODE_SANYO_AC152 || DECODE_DAIKIN312 || \
|
||||
DECODE_CARRIER_AC84 || DECODE_YORK || \
|
||||
false)
|
||||
// Add any DECODE to the above if it uses result->state (see kStateSizeMax)
|
||||
// you might also want to add the protocol to hasACState function
|
||||
|
@ -1104,8 +1133,12 @@ enum decode_type_t {
|
|||
BOSCH144, // 120
|
||||
SANYO_AC152,
|
||||
DAIKIN312,
|
||||
GORENJE,
|
||||
WOWWEE,
|
||||
CARRIER_AC84, // 125
|
||||
YORK,
|
||||
// Add new entries before this one, and update it to point to the last entry.
|
||||
kLastDecodeType = DAIKIN312,
|
||||
kLastDecodeType = YORK,
|
||||
};
|
||||
|
||||
// Message lengths & required repeat values
|
||||
|
@ -1123,7 +1156,13 @@ const uint16_t kAmcorStateLength = 8;
|
|||
const uint16_t kAmcorBits = kAmcorStateLength * 8;
|
||||
const uint16_t kAmcorDefaultRepeat = kSingleRepeat;
|
||||
const uint16_t kArgoStateLength = 12;
|
||||
const uint16_t kArgoShortStateLength = 4;
|
||||
const uint16_t kArgoBits = kArgoStateLength * 8;
|
||||
const uint16_t kArgoShortBits = kArgoShortStateLength * 8;
|
||||
const uint16_t kArgo3AcControlStateLength = 6; // Bytes
|
||||
const uint16_t kArgo3iFeelReportStateLength = 2; // Bytes
|
||||
const uint16_t kArgo3TimerStateLength = 9; // Bytes
|
||||
const uint16_t kArgo3ConfigStateLength = 4; // Bytes
|
||||
const uint16_t kArgoDefaultRepeat = kNoRepeat;
|
||||
const uint16_t kArrisBits = 32;
|
||||
const uint16_t kBosch144StateLength = 18;
|
||||
|
@ -1137,6 +1176,9 @@ const uint16_t kCarrierAc40Bits = 40;
|
|||
const uint16_t kCarrierAc40MinRepeat = 2;
|
||||
const uint16_t kCarrierAc64Bits = 64;
|
||||
const uint16_t kCarrierAc64MinRepeat = kNoRepeat;
|
||||
const uint16_t kCarrierAc84StateLength = 11;
|
||||
const uint16_t kCarrierAc84Bits = kCarrierAc84StateLength * 8 - 4;
|
||||
const uint16_t kCarrierAc84MinRepeat = kNoRepeat;
|
||||
const uint16_t kCarrierAc128StateLength = 16;
|
||||
const uint16_t kCarrierAc128Bits = kCarrierAc128StateLength * 8;
|
||||
const uint16_t kCarrierAc128MinRepeat = kNoRepeat;
|
||||
|
@ -1203,6 +1245,7 @@ const uint16_t kGicableBits = 16;
|
|||
const uint16_t kGicableMinRepeat = kSingleRepeat;
|
||||
const uint16_t kGoodweatherBits = 48;
|
||||
const uint16_t kGoodweatherMinRepeat = kNoRepeat;
|
||||
const uint16_t kGorenjeBits = 8;
|
||||
const uint16_t kGreeStateLength = 8;
|
||||
const uint16_t kGreeBits = kGreeStateLength * 8;
|
||||
const uint16_t kGreeDefaultRepeat = kNoRepeat;
|
||||
|
@ -1292,6 +1335,8 @@ const uint16_t kNeoclimaBits = kNeoclimaStateLength * 8;
|
|||
const uint16_t kNeoclimaMinRepeat = kNoRepeat;
|
||||
const uint16_t kPanasonicBits = 48;
|
||||
const uint32_t kPanasonicManufacturer = 0x4004;
|
||||
const uint32_t kPanasonic40Manufacturer = 0x34;
|
||||
const uint16_t kPanasonic40Bits = 40;
|
||||
const uint16_t kPanasonicAcStateLength = 27;
|
||||
const uint16_t kPanasonicAcStateShortLength = 16;
|
||||
const uint16_t kPanasonicAcBits = kPanasonicAcStateLength * 8;
|
||||
|
@ -1372,6 +1417,8 @@ const uint16_t kWhirlpoolAcStateLength = 21;
|
|||
const uint16_t kWhirlpoolAcBits = kWhirlpoolAcStateLength * 8;
|
||||
const uint16_t kWhirlpoolAcDefaultRepeat = kNoRepeat;
|
||||
const uint16_t kWhynterBits = 32;
|
||||
const uint16_t kWowweeBits = 11;
|
||||
const uint16_t kWowweeDefaultRepeat = kNoRepeat;
|
||||
const uint8_t kVestelAcBits = 56;
|
||||
const uint16_t kXmpBits = 64;
|
||||
const uint16_t kZepealBits = 16;
|
||||
|
@ -1386,6 +1433,8 @@ const uint16_t kRhossStateLength = 12;
|
|||
const uint16_t kRhossBits = kRhossStateLength * 8;
|
||||
const uint16_t kRhossDefaultRepeat = 0;
|
||||
const uint16_t kClimaButlerBits = 52;
|
||||
const uint16_t kYorkBits = 136;
|
||||
const uint16_t kYorkStateLength = 17;
|
||||
|
||||
|
||||
// Legacy defines. (Deprecated)
|
||||
|
|
|
@ -603,7 +603,10 @@ uint16_t IRsend::minRepeats(const decode_type_t protocol) {
|
|||
uint16_t IRsend::defaultBits(const decode_type_t protocol) {
|
||||
switch (protocol) {
|
||||
case MULTIBRACKETS:
|
||||
case GORENJE:
|
||||
return 8;
|
||||
case WOWWEE:
|
||||
return 11;
|
||||
case RC5:
|
||||
case SYMPHONY:
|
||||
return 12;
|
||||
|
@ -690,6 +693,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
|
|||
return kBosch144Bits;
|
||||
case CORONA_AC:
|
||||
return kCoronaAcBits;
|
||||
case CARRIER_AC84:
|
||||
return kCarrierAc84Bits;
|
||||
case CARRIER_AC128:
|
||||
return kCarrierAc128Bits;
|
||||
case DAIKIN:
|
||||
|
@ -791,6 +796,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
|
|||
return kWhirlpoolAcBits;
|
||||
case XMP:
|
||||
return kXmpBits;
|
||||
case YORK:
|
||||
return kYorkBits;
|
||||
// No default amount of bits.
|
||||
case FUJITSU_AC:
|
||||
case MWM:
|
||||
|
@ -916,6 +923,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data,
|
|||
sendGoodweather(data, nbits, min_repeat);
|
||||
break;
|
||||
#endif
|
||||
#if SEND_GORENJE
|
||||
case GORENJE:
|
||||
sendGorenje(data, nbits, min_repeat);
|
||||
break;
|
||||
#endif
|
||||
#if SEND_GREE
|
||||
case GREE:
|
||||
sendGree(data, nbits, min_repeat);
|
||||
|
@ -1114,6 +1126,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data,
|
|||
sendWhynter(data, nbits, min_repeat);
|
||||
break;
|
||||
#endif
|
||||
#if SEND_WOWWEE
|
||||
case WOWWEE:
|
||||
sendWowwee(data, nbits, min_repeat);
|
||||
break;
|
||||
#endif // SEND_WOWWEE
|
||||
#if SEND_XMP
|
||||
case XMP:
|
||||
sendXmp(data, nbits, min_repeat);
|
||||
|
@ -1159,6 +1176,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
|
|||
sendBosch144(state, nbytes);
|
||||
break;
|
||||
#endif // SEND_BOSCH144
|
||||
#if SEND_CARRIER_AC84
|
||||
case CARRIER_AC84:
|
||||
sendCarrierAC84(state, nbytes);
|
||||
break;
|
||||
#endif // SEND_CARRIER_AC84
|
||||
#if SEND_CARRIER_AC128
|
||||
case CARRIER_AC128:
|
||||
sendCarrierAC128(state, nbytes);
|
||||
|
@ -1407,6 +1429,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
|
|||
sendWhirlpoolAC(state, nbytes);
|
||||
break;
|
||||
#endif // SEND_WHIRLPOOL_AC
|
||||
#if SEND_YORK
|
||||
case YORK:
|
||||
sendYork(state, nbytes);
|
||||
break;
|
||||
#endif // SEND_YORK
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ const uint8_t kDutyMax = 100; // Percentage
|
|||
const uint16_t kMaxAccurateUsecDelay = 16383;
|
||||
// Usecs to wait between messages we don't know the proper gap time.
|
||||
const uint32_t kDefaultMessageGap = 100000;
|
||||
/// Placeholder for missing sensor temp value
|
||||
/// @note Not using "-1" as it may be a valid external temp
|
||||
const float kNoTempValue = -100.0;
|
||||
|
||||
/// Enumerators and Structures for the Common A/C API.
|
||||
namespace stdAc {
|
||||
|
@ -56,14 +59,15 @@ enum class opmode_t {
|
|||
|
||||
/// Common A/C settings for Fan Speeds.
|
||||
enum class fanspeed_t {
|
||||
kAuto = 0,
|
||||
kMin = 1,
|
||||
kLow = 2,
|
||||
kMedium = 3,
|
||||
kHigh = 4,
|
||||
kMax = 5,
|
||||
kAuto = 0,
|
||||
kMin = 1,
|
||||
kLow = 2,
|
||||
kMedium = 3,
|
||||
kHigh = 4,
|
||||
kMax = 5,
|
||||
kMediumHigh = 6,
|
||||
// Add new entries before this one, and update it to point to the last entry
|
||||
kLastFanspeedEnum = kMax,
|
||||
kLastFanspeedEnum = kMediumHigh,
|
||||
};
|
||||
|
||||
/// Common A/C settings for Vertical Swing.
|
||||
|
@ -75,8 +79,21 @@ enum class swingv_t {
|
|||
kMiddle = 3,
|
||||
kLow = 4,
|
||||
kLowest = 5,
|
||||
kUpperMiddle = 6,
|
||||
// Add new entries before this one, and update it to point to the last entry
|
||||
kLastSwingvEnum = kLowest,
|
||||
kLastSwingvEnum = kUpperMiddle,
|
||||
};
|
||||
|
||||
/// @brief Tyoe of A/C command (if the remote uses different codes for each)
|
||||
/// @note Most remotes support only a single command or aggregate multiple
|
||||
/// into one (e.g. control+timer). Use @c kControlCommand in such case
|
||||
enum class ac_command_t {
|
||||
kControlCommand = 0,
|
||||
kSensorTempReport = 1,
|
||||
kTimerCommand = 2,
|
||||
kConfigCommand = 3,
|
||||
// Add new entries before this one, and update it to point to the last entry
|
||||
kLastAcCommandEnum = kConfigCommand,
|
||||
};
|
||||
|
||||
/// Common A/C settings for Horizontal Swing.
|
||||
|
@ -113,6 +130,9 @@ struct state_t {
|
|||
bool beep = false;
|
||||
int16_t sleep = -1; // `-1` means off.
|
||||
int16_t clock = -1; // `-1` means not set.
|
||||
stdAc::ac_command_t command = stdAc::ac_command_t::kControlCommand;
|
||||
bool iFeel = false;
|
||||
float sensorTemperature = kNoTempValue; // `kNoTempValue` means not set.
|
||||
};
|
||||
}; // namespace stdAc
|
||||
|
||||
|
@ -202,6 +222,11 @@ enum lg_ac_remote_model_t {
|
|||
LG6711A20083V, // (5) Same as GE6711AR2853M, but only SwingV toggle.
|
||||
};
|
||||
|
||||
/// Argo A/C model numbers
|
||||
enum argo_ac_remote_model_t {
|
||||
SAC_WREM2 = 1, // (1) ARGO WREM2 remote (default)
|
||||
SAC_WREM3 // (2) ARGO WREM3 remote (touch buttons), bit-len vary by cmd
|
||||
};
|
||||
|
||||
// Classes
|
||||
|
||||
|
@ -519,14 +544,22 @@ class IRsend {
|
|||
const uint16_t nbits = kGoodweatherBits,
|
||||
const uint16_t repeat = kGoodweatherMinRepeat);
|
||||
#endif // SEND_GOODWEATHER
|
||||
#if SEND_GORENJE
|
||||
void sendGorenje(const uint64_t data, const uint16_t nbits = kGorenjeBits,
|
||||
const uint16_t repeat = kNoRepeat);
|
||||
#endif // SEND_GORENJE
|
||||
#if SEND_PRONTO
|
||||
void sendPronto(uint16_t data[], uint16_t len, uint16_t repeat = kNoRepeat);
|
||||
#endif
|
||||
#if SEND_ARGO
|
||||
void sendArgo(const unsigned char data[],
|
||||
const uint16_t nbytes = kArgoStateLength,
|
||||
const uint16_t repeat = kArgoDefaultRepeat,
|
||||
bool sendFooter = false);
|
||||
void sendArgoWREM3(const unsigned char data[],
|
||||
const uint16_t nbytes = kArgoStateLength,
|
||||
const uint16_t repeat = kArgoDefaultRepeat);
|
||||
#endif
|
||||
#endif // SEND_ARGO
|
||||
#if SEND_TROTEC
|
||||
void sendTrotec(const unsigned char data[],
|
||||
const uint16_t nbytes = kTrotecStateLength,
|
||||
|
@ -575,6 +608,11 @@ class IRsend {
|
|||
void sendCarrierAC64(uint64_t data, uint16_t nbits = kCarrierAc64Bits,
|
||||
uint16_t repeat = kCarrierAc64MinRepeat);
|
||||
#endif
|
||||
#if SEND_CARRIER_AC84
|
||||
void sendCarrierAC84(const uint8_t data[],
|
||||
const uint16_t nbytes = kCarrierAc84StateLength,
|
||||
const uint16_t repeat = kNoRepeat);
|
||||
#endif // SEND_CARRIER_AC84
|
||||
#if SEND_CARRIER_AC128
|
||||
void sendCarrierAC128(const uint8_t data[],
|
||||
uint16_t nbytes = kCarrierAc128StateLength,
|
||||
|
@ -837,6 +875,15 @@ class IRsend {
|
|||
const uint16_t nbytes = kBosch144StateLength,
|
||||
const uint16_t repeat = kNoRepeat);
|
||||
#endif // SEND_BOSCH144
|
||||
#if SEND_WOWWEE
|
||||
void sendWowwee(const uint64_t data, const uint16_t nbits = kWowweeBits,
|
||||
const uint16_t repeat = kWowweeDefaultRepeat);
|
||||
#endif // SEND_WOWWEE
|
||||
#if SEND_YORK
|
||||
void sendYork(const unsigned char data[],
|
||||
const uint16_t nbytes = kYorkStateLength,
|
||||
const uint16_t repeat = kNoRepeat);
|
||||
#endif // SEND_YORK
|
||||
|
||||
protected:
|
||||
#ifdef UNIT_TEST
|
||||
|
|
|
@ -68,10 +68,13 @@ IRTEXT_CONST_STRING(kOffTimerStr, D_STR_OFFTIMER); ///< "Off Timer"
|
|||
IRTEXT_CONST_STRING(kTimerModeStr, D_STR_TIMERMODE); ///< "Timer Mode"
|
||||
IRTEXT_CONST_STRING(kClockStr, D_STR_CLOCK); ///< "Clock"
|
||||
IRTEXT_CONST_STRING(kCommandStr, D_STR_COMMAND); ///< "Command"
|
||||
IRTEXT_CONST_STRING(kConfigCommandStr, D_STR_CONFIG); ///< "Config"
|
||||
IRTEXT_CONST_STRING(kControlCommandStr, D_STR_CONTROL); ///< "Control"
|
||||
IRTEXT_CONST_STRING(kXFanStr, D_STR_XFAN); ///< "XFan"
|
||||
IRTEXT_CONST_STRING(kHealthStr, D_STR_HEALTH); ///< "Health"
|
||||
IRTEXT_CONST_STRING(kModelStr, D_STR_MODEL); ///< "Model"
|
||||
IRTEXT_CONST_STRING(kTempStr, D_STR_TEMP); ///< "Temp"
|
||||
IRTEXT_CONST_STRING(kIFeelReportStr, D_STR_IFEELREPORT); ///< "IFeel Report"
|
||||
IRTEXT_CONST_STRING(kIFeelStr, D_STR_IFEEL); ///< "IFeel"
|
||||
IRTEXT_CONST_STRING(kHumidStr, D_STR_HUMID); ///< "Humid"
|
||||
IRTEXT_CONST_STRING(kSaveStr, D_STR_SAVE); ///< "Save"
|
||||
|
@ -123,6 +126,7 @@ IRTEXT_CONST_STRING(kOutsideStr, D_STR_OUTSIDE); ///< "Outside"
|
|||
IRTEXT_CONST_STRING(kLoudStr, D_STR_LOUD); ///< "Loud"
|
||||
IRTEXT_CONST_STRING(kLowerStr, D_STR_LOWER); ///< "Lower"
|
||||
IRTEXT_CONST_STRING(kUpperStr, D_STR_UPPER); ///< "Upper"
|
||||
IRTEXT_CONST_STRING(kUpperMiddleStr, D_STR_UPPER_MIDDLE); ///< "Upper-Middle"
|
||||
IRTEXT_CONST_STRING(kBreezeStr, D_STR_BREEZE); ///< "Breeze"
|
||||
IRTEXT_CONST_STRING(kCirculateStr, D_STR_CIRCULATE); ///< "Circulate"
|
||||
IRTEXT_CONST_STRING(kCeilingStr, D_STR_CEILING); ///< "Ceiling"
|
||||
|
@ -160,6 +164,7 @@ IRTEXT_CONST_STRING(kMaxStr, D_STR_MAX); ///< "Max"
|
|||
IRTEXT_CONST_STRING(kMaximumStr, D_STR_MAXIMUM); ///< "Maximum"
|
||||
IRTEXT_CONST_STRING(kMinStr, D_STR_MIN); ///< "Min"
|
||||
IRTEXT_CONST_STRING(kMinimumStr, D_STR_MINIMUM); ///< "Minimum"
|
||||
IRTEXT_CONST_STRING(kMedHighStr, D_STR_MED_HIGH); ///< "Med-high"
|
||||
IRTEXT_CONST_STRING(kMedStr, D_STR_MED); ///< "Med"
|
||||
IRTEXT_CONST_STRING(kMediumStr, D_STR_MEDIUM); ///< "Medium"
|
||||
|
||||
|
@ -205,6 +210,13 @@ IRTEXT_CONST_STRING(kSwingVModeStr, D_STR_SWINGVMODE); ///< "Swing(V) Mode"
|
|||
IRTEXT_CONST_STRING(kSwingVToggleStr, D_STR_SWINGVTOGGLE); ///<
|
||||
///< "Swing(V) Toggle"
|
||||
IRTEXT_CONST_STRING(kTurboToggleStr, D_STR_TURBOTOGGLE); ///< "Turbo Toggle"
|
||||
IRTEXT_CONST_STRING(kSetTimerCommandStr, D_STR_SET_TIMER); ///< "Set Timer"
|
||||
IRTEXT_CONST_STRING(kScheduleStr, D_STR_SCHEDULE); ///< "Schedule"
|
||||
IRTEXT_CONST_STRING(kChStr, D_STR_CH); ///< "CH#"
|
||||
IRTEXT_CONST_STRING(kTimerActiveDaysStr, D_STR_TIMER_ACTIVE_DAYS);
|
||||
///< "TimerActiveDays"
|
||||
IRTEXT_CONST_STRING(kKeyStr, D_STR_KEY); ///< "Key"
|
||||
IRTEXT_CONST_STRING(kValueStr, D_STR_VALUE); ///< "Value"
|
||||
|
||||
// Separators & Punctuation
|
||||
const char kTimeSep = D_CHR_TIME_SEP; ///< ':'
|
||||
|
@ -281,6 +293,8 @@ IRTEXT_CONST_STRING(k122lzfStr, D_STR_122LZF); ///< "122LZF"
|
|||
IRTEXT_CONST_STRING(kDg11j13aStr, D_STR_DG11J13A); ///< "DG11J13A"
|
||||
IRTEXT_CONST_STRING(kDg11j104Str, D_STR_DG11J104); ///< "DG11J104"
|
||||
IRTEXT_CONST_STRING(kDg11j191Str, D_STR_DG11J191); ///< "DG11J191"
|
||||
IRTEXT_CONST_STRING(kArgoWrem2Str, D_STR_ARGO_WREM2); ///< "WREM3"
|
||||
IRTEXT_CONST_STRING(kArgoWrem3Str, D_STR_ARGO_WREM3); ///< "WREM3"
|
||||
|
||||
#define D_STR_UNSUPPORTED "?" // Unsupported protocols will be showing as
|
||||
// a question mark, check for length > 1
|
||||
|
@ -533,6 +547,14 @@ IRTEXT_CONST_BLOB_DECL(kAllProtocolNamesStr) {
|
|||
D_STR_SANYO_AC152, D_STR_UNSUPPORTED) "\x0"
|
||||
COND(DECODE_DAIKIN312 || SEND_DAIKIN312,
|
||||
D_STR_DAIKIN312, D_STR_UNSUPPORTED) "\x0"
|
||||
COND(DECODE_GORENJE || SEND_GORENJE,
|
||||
D_STR_GORENJE, D_STR_UNSUPPORTED) "\x0"
|
||||
COND(DECODE_WOWWEE || SEND_WOWWEE,
|
||||
D_STR_WOWWEE, D_STR_UNSUPPORTED) "\x0"
|
||||
COND(DECODE_CARRIER_AC84 || SEND_CARRIER_AC84,
|
||||
D_STR_CARRIER_AC84, D_STR_UNSUPPORTED) "\x0"
|
||||
COND(DECODE_YORK || SEND_YORK,
|
||||
D_STR_YORK, D_STR_UNSUPPORTED) "\x0"
|
||||
///< New protocol (macro) strings should be added just above this line.
|
||||
"\x0" ///< This string requires double null termination.
|
||||
};
|
||||
|
|
|
@ -39,6 +39,8 @@ extern IRTEXT_CONST_PTR(kAkb73757604Str);
|
|||
extern IRTEXT_CONST_PTR(kAkb74955603Str);
|
||||
extern IRTEXT_CONST_PTR(kAkb75215403Str);
|
||||
extern IRTEXT_CONST_PTR(kArdb1Str);
|
||||
extern IRTEXT_CONST_PTR(kArgoWrem2Str);
|
||||
extern IRTEXT_CONST_PTR(kArgoWrem3Str);
|
||||
extern IRTEXT_CONST_PTR(kArjw2Str);
|
||||
extern IRTEXT_CONST_PTR(kArrah2eStr);
|
||||
extern IRTEXT_CONST_PTR(kArreb1eStr);
|
||||
|
@ -57,6 +59,7 @@ extern IRTEXT_CONST_PTR(kCelsiusFahrenheitStr);
|
|||
extern IRTEXT_CONST_PTR(kCelsiusStr);
|
||||
extern IRTEXT_CONST_PTR(kCentreStr);
|
||||
extern IRTEXT_CONST_PTR(kChangeStr);
|
||||
extern IRTEXT_CONST_PTR(kChStr);
|
||||
extern IRTEXT_CONST_PTR(kCirculateStr);
|
||||
extern IRTEXT_CONST_PTR(kCkpStr);
|
||||
extern IRTEXT_CONST_PTR(kCleanStr);
|
||||
|
@ -66,6 +69,8 @@ extern IRTEXT_CONST_PTR(kColonSpaceStr);
|
|||
extern IRTEXT_CONST_PTR(kComfortStr);
|
||||
extern IRTEXT_CONST_PTR(kCommaSpaceStr);
|
||||
extern IRTEXT_CONST_PTR(kCommandStr);
|
||||
extern IRTEXT_CONST_PTR(kConfigCommandStr);
|
||||
extern IRTEXT_CONST_PTR(kControlCommandStr);
|
||||
extern IRTEXT_CONST_PTR(kCoolStr);
|
||||
extern IRTEXT_CONST_PTR(kCoolingStr);
|
||||
extern IRTEXT_CONST_PTR(kDashStr);
|
||||
|
@ -109,6 +114,7 @@ extern IRTEXT_CONST_PTR(kHoldStr);
|
|||
extern IRTEXT_CONST_PTR(kHourStr);
|
||||
extern IRTEXT_CONST_PTR(kHoursStr);
|
||||
extern IRTEXT_CONST_PTR(kHumidStr);
|
||||
extern IRTEXT_CONST_PTR(kIFeelReportStr);
|
||||
extern IRTEXT_CONST_PTR(kIFeelStr);
|
||||
extern IRTEXT_CONST_PTR(kISeeStr);
|
||||
extern IRTEXT_CONST_PTR(kIdStr);
|
||||
|
@ -116,6 +122,7 @@ extern IRTEXT_CONST_PTR(kIndirectStr);
|
|||
extern IRTEXT_CONST_PTR(kInsideStr);
|
||||
extern IRTEXT_CONST_PTR(kIonStr);
|
||||
extern IRTEXT_CONST_PTR(kJkeStr);
|
||||
extern IRTEXT_CONST_PTR(kKeyStr);
|
||||
extern IRTEXT_CONST_PTR(kKkg29ac1Str);
|
||||
extern IRTEXT_CONST_PTR(kKkg9ac1Str);
|
||||
extern IRTEXT_CONST_PTR(kLastStr);
|
||||
|
@ -139,6 +146,7 @@ extern IRTEXT_CONST_PTR(kMaxRightNoSpaceStr);
|
|||
extern IRTEXT_CONST_PTR(kMaxRightStr);
|
||||
extern IRTEXT_CONST_PTR(kMaxStr);
|
||||
extern IRTEXT_CONST_PTR(kMaximumStr);
|
||||
extern IRTEXT_CONST_PTR(kMedHighStr);
|
||||
extern IRTEXT_CONST_PTR(kMedStr);
|
||||
extern IRTEXT_CONST_PTR(kMediumStr);
|
||||
extern IRTEXT_CONST_PTR(kMidStr);
|
||||
|
@ -188,8 +196,10 @@ extern IRTEXT_CONST_PTR(kRlt0541htaaStr);
|
|||
extern IRTEXT_CONST_PTR(kRlt0541htabStr);
|
||||
extern IRTEXT_CONST_PTR(kRoomStr);
|
||||
extern IRTEXT_CONST_PTR(kSaveStr);
|
||||
extern IRTEXT_CONST_PTR(kScheduleStr);
|
||||
extern IRTEXT_CONST_PTR(kSecondStr);
|
||||
extern IRTEXT_CONST_PTR(kSecondsStr);
|
||||
extern IRTEXT_CONST_PTR(kSensorReportStr);
|
||||
extern IRTEXT_CONST_PTR(kSensorStr);
|
||||
extern IRTEXT_CONST_PTR(kSensorTempStr);
|
||||
extern IRTEXT_CONST_PTR(kSetStr);
|
||||
|
@ -213,7 +223,9 @@ extern IRTEXT_CONST_PTR(kTempDownStr);
|
|||
extern IRTEXT_CONST_PTR(kTempStr);
|
||||
extern IRTEXT_CONST_PTR(kTempUpStr);
|
||||
extern IRTEXT_CONST_PTR(kThreeLetterDayOfWeekStr);
|
||||
extern IRTEXT_CONST_PTR(kTimerActiveDaysStr);
|
||||
extern IRTEXT_CONST_PTR(kTimerModeStr);
|
||||
extern IRTEXT_CONST_PTR(kSetTimerCommandStr);
|
||||
extern IRTEXT_CONST_PTR(kTimerStr);
|
||||
extern IRTEXT_CONST_PTR(kToggleStr);
|
||||
extern IRTEXT_CONST_PTR(kTopStr);
|
||||
|
@ -224,6 +236,8 @@ extern IRTEXT_CONST_PTR(kTypeStr);
|
|||
extern IRTEXT_CONST_PTR(kUnknownStr);
|
||||
extern IRTEXT_CONST_PTR(kUpStr);
|
||||
extern IRTEXT_CONST_PTR(kUpperStr);
|
||||
extern IRTEXT_CONST_PTR(kUpperMiddleStr);
|
||||
extern IRTEXT_CONST_PTR(kValueStr);
|
||||
extern IRTEXT_CONST_PTR(kV9014557AStr);
|
||||
extern IRTEXT_CONST_PTR(kV9014557BStr);
|
||||
extern IRTEXT_CONST_PTR(kVaneStr);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#endif
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
@ -173,6 +174,7 @@ bool hasACState(const decode_type_t protocol) {
|
|||
case AMCOR:
|
||||
case ARGO:
|
||||
case BOSCH144:
|
||||
case CARRIER_AC84:
|
||||
case CARRIER_AC128:
|
||||
case CORONA_AC:
|
||||
case DAIKIN:
|
||||
|
@ -224,6 +226,7 @@ bool hasACState(const decode_type_t protocol) {
|
|||
case TROTEC_3550:
|
||||
case VOLTAS:
|
||||
case WHIRLPOOL_AC:
|
||||
case YORK:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -304,7 +307,7 @@ String resultToSourceCode(const decode_results * const results) {
|
|||
if (results->decode_type != UNKNOWN) {
|
||||
if (hasState) {
|
||||
#if DECODE_AC
|
||||
uint16_t nbytes = results->bits / 8;
|
||||
uint16_t nbytes = ceil(static_cast<float>(results->bits) / 8.0);
|
||||
output += F("uint8_t state[");
|
||||
output += uint64ToString(nbytes);
|
||||
output += F("] = {");
|
||||
|
@ -695,6 +698,13 @@ namespace irutils {
|
|||
default: return kUnknownStr;
|
||||
}
|
||||
break;
|
||||
case decode_type_t::ARGO:
|
||||
switch (model) {
|
||||
case argo_ac_remote_model_t::SAC_WREM2: return kArgoWrem2Str;
|
||||
case argo_ac_remote_model_t::SAC_WREM3: return kArgoWrem3Str;
|
||||
default: return kUnknownStr;
|
||||
}
|
||||
break;
|
||||
default: return kUnknownStr;
|
||||
}
|
||||
}
|
||||
|
@ -722,10 +732,12 @@ namespace irutils {
|
|||
/// @param[in] celsius Is the temp Celsius or Fahrenheit.
|
||||
/// true is C, false is F
|
||||
/// @param[in] precomma Should the output string start with ", " or not?
|
||||
/// @param[in] isSensorTemp Is the value a room (ambient) temp. or target?
|
||||
/// @return The resulting String.
|
||||
String addTempToString(const uint16_t degrees, const bool celsius,
|
||||
const bool precomma) {
|
||||
String result = addIntToString(degrees, kTempStr, precomma);
|
||||
const bool precomma, const bool isSensorTemp) {
|
||||
String result = addIntToString(degrees, (isSensorTemp)?
|
||||
kSensorTempStr : kTempStr, precomma);
|
||||
result += celsius ? 'C' : 'F';
|
||||
return result;
|
||||
}
|
||||
|
@ -736,12 +748,14 @@ namespace irutils {
|
|||
/// @param[in] celsius Is the temp Celsius or Fahrenheit.
|
||||
/// true is C, false is F
|
||||
/// @param[in] precomma Should the output string start with ", " or not?
|
||||
/// @param[in] isSensorTemp Is the value a room (ambient) temp. or target?
|
||||
/// @return The resulting String.
|
||||
String addTempFloatToString(const float degrees, const bool celsius,
|
||||
const bool precomma) {
|
||||
const bool precomma, const bool isSensorTemp) {
|
||||
String result = "";
|
||||
result.reserve(14); // Assuming ", Temp: XXX.5F" is the largest.
|
||||
result += addIntToString(degrees, kTempStr, precomma);
|
||||
result.reserve(21); // Assuming ", Sensor Temp: XXX.5F" is the largest.
|
||||
result += addIntToString(degrees, (isSensorTemp)?
|
||||
kSensorTempStr : kTempStr, precomma);
|
||||
// Is it a half degree?
|
||||
if (((uint16_t)(2 * degrees)) & 1) result += F(".5");
|
||||
result += celsius ? 'C' : 'F';
|
||||
|
@ -788,43 +802,57 @@ namespace irutils {
|
|||
result.reserve(19); // ", Day: N (UNKNOWN)"
|
||||
result += addIntToString(day_of_week, kDayStr, precomma);
|
||||
result += kSpaceLBraceStr;
|
||||
result += dayToString(day_of_week, offset);
|
||||
return result + ')';
|
||||
}
|
||||
|
||||
/// Create a String of the 3-letter day of the week from a numerical day of
|
||||
/// the week. e.g. "Mon"
|
||||
/// @param[in] day_of_week A numerical version of the sequential day of the
|
||||
/// week. e.g. Sunday = 1, Monday = 2, ..., Saturday = 7
|
||||
/// @param[in] offset Days to offset by.
|
||||
/// e.g. For different day starting the week.
|
||||
/// @return The resulting String.
|
||||
String dayToString(const uint8_t day_of_week, const int8_t offset) {
|
||||
if ((uint8_t)(day_of_week + offset) < 7)
|
||||
#if UNIT_TEST
|
||||
result += String(kThreeLetterDayOfWeekStr).substr(
|
||||
(day_of_week + offset) * 3, 3);
|
||||
return String(kThreeLetterDayOfWeekStr).substr(
|
||||
(day_of_week + offset) * 3, 3);
|
||||
#else // UNIT_TEST
|
||||
result += String(kThreeLetterDayOfWeekStr).substring(
|
||||
(day_of_week + offset) * 3, (day_of_week + offset) * 3 + 3);
|
||||
return String(kThreeLetterDayOfWeekStr).substring(
|
||||
(day_of_week + offset) * 3, (day_of_week + offset) * 3 + 3);
|
||||
#endif // UNIT_TEST
|
||||
else
|
||||
result += kUnknownStr;
|
||||
return result + ')';
|
||||
return kUnknownStr;
|
||||
}
|
||||
|
||||
/// Create a String of human output for the given fan speed.
|
||||
/// e.g. "Fan: 0 (Auto)"
|
||||
/// @param[in] speed The numeric speed of the fan to display.
|
||||
/// @param[in] high The numeric value for High speed.
|
||||
/// @param[in] high The numeric value for High speed. (second highest)
|
||||
/// @param[in] low The numeric value for Low speed.
|
||||
/// @param[in] automatic The numeric value for Auto speed.
|
||||
/// @param[in] quiet The numeric value for Quiet speed.
|
||||
/// @param[in] medium The numeric value for Medium speed.
|
||||
/// @param[in] maximum The numeric value for Highest speed. (if > high)
|
||||
/// @param[in] medium_high The numeric value for third-highest speed.
|
||||
/// (if > medium)
|
||||
/// @return The resulting String.
|
||||
String addFanToString(const uint8_t speed, const uint8_t high,
|
||||
const uint8_t low, const uint8_t automatic,
|
||||
const uint8_t quiet, const uint8_t medium,
|
||||
const uint8_t maximum) {
|
||||
const uint8_t maximum, const uint8_t medium_high) {
|
||||
String result = "";
|
||||
result.reserve(21); // ", Fan: NNN (UNKNOWN)"
|
||||
result += addIntToString(speed, kFanStr);
|
||||
result += kSpaceLBraceStr;
|
||||
if (speed == high) result += kHighStr;
|
||||
else if (speed == low) result += kLowStr;
|
||||
else if (speed == automatic) result += kAutoStr;
|
||||
else if (speed == quiet) result += kQuietStr;
|
||||
else if (speed == medium) result += kMediumStr;
|
||||
else if (speed == maximum) result += kMaximumStr;
|
||||
if (speed == high) result += kHighStr;
|
||||
else if (speed == low) result += kLowStr;
|
||||
else if (speed == automatic) result += kAutoStr;
|
||||
else if (speed == quiet) result += kQuietStr;
|
||||
else if (speed == medium) result += kMediumStr;
|
||||
else if (speed == maximum) result += kMaximumStr;
|
||||
else if (speed == medium_high) result += kMedHighStr;
|
||||
else
|
||||
result += kUnknownStr;
|
||||
return result + ')';
|
||||
|
@ -950,6 +978,106 @@ namespace irutils {
|
|||
return result + ')';
|
||||
}
|
||||
|
||||
/// @brief Create a String of human output for the given timer setting.
|
||||
/// e.g. "Timer Mode: 2 (Schedule 1)"
|
||||
/// @param[in] timerMode The numeric value of the timer mode to display.
|
||||
/// @param[in] noTimer The numeric value for no timer (off)
|
||||
/// @param[in] delayTimer The numeric value for delay (sleep) timer
|
||||
/// @param[in] schedule1 The numeric value for schedule timer #1
|
||||
/// @param[in] schedule2 The numeric value for schedule timer #2
|
||||
/// @param[in] schedule3 The numeric value for schedule timer #3
|
||||
/// @param[in] precomma Should the output string start with ", " or not?
|
||||
/// @return String representation
|
||||
String addTimerModeToString(const uint8_t timerMode, const uint8_t noTimer,
|
||||
const uint8_t delayTimer, const uint8_t schedule1,
|
||||
const uint8_t schedule2, const uint8_t schedule3,
|
||||
const bool precomma) {
|
||||
String result = "";
|
||||
result.reserve(28); // ", Timer Mode: 2 (Schedule 1)"
|
||||
result += addIntToString(timerMode, kTimerModeStr, precomma);
|
||||
result += kSpaceLBraceStr;
|
||||
if (timerMode == noTimer) {
|
||||
result += kOffStr;
|
||||
} else if (timerMode == delayTimer) {
|
||||
result += kSleepTimerStr;
|
||||
} else if (timerMode == schedule1) {
|
||||
result += kScheduleStr;
|
||||
result += '1';
|
||||
} else if (timerMode == schedule2) {
|
||||
result += kScheduleStr;
|
||||
result += '2';
|
||||
} else if (timerMode == schedule3) {
|
||||
result += kScheduleStr;
|
||||
result += '3';
|
||||
} else {
|
||||
result += kUnknownStr;
|
||||
}
|
||||
return result + ')';
|
||||
}
|
||||
|
||||
/// @brief Create a String of human output for the given channel
|
||||
/// e.g. "[CH#0]"
|
||||
/// @param channel The numeric value of the channel to display.
|
||||
/// @return String representation
|
||||
String channelToString(const uint8_t channel) {
|
||||
String result = "";
|
||||
result.reserve(6); // "[CH#4]"
|
||||
result += "[";
|
||||
result += kChStr;
|
||||
result += uint64ToString(channel);
|
||||
result += "]";
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief Create a String of human output for the given command type
|
||||
/// e.g. "IFeel Report"
|
||||
/// @param irCommandType The numeric value of the command type to display.
|
||||
/// @param acControlCmd The numeric value of the "control" (default) command
|
||||
/// @param iFeelReportCmd The numeric value of the sensor temperature command
|
||||
/// @param timerCmd The numeric value of the timer config IR command
|
||||
/// @param configCmd The numeric value of the config param set IR command
|
||||
/// @return String representation
|
||||
String irCommandTypeToString(uint8_t irCommandType, uint8_t acControlCmd,
|
||||
uint8_t iFeelReportCmd, uint8_t timerCmd,
|
||||
uint8_t configCmd) {
|
||||
String result = "";
|
||||
result.reserve(12); // "IFeel Report"
|
||||
if (irCommandType == acControlCmd) {
|
||||
result += kCommandStr;
|
||||
} else if (irCommandType == iFeelReportCmd) {
|
||||
result += kIFeelReportStr;
|
||||
} else if (irCommandType == timerCmd) {
|
||||
result += kTimerStr;
|
||||
} else if (irCommandType == configCmd) {
|
||||
result += kConfigCommandStr;
|
||||
} else {
|
||||
result += kUnknownStr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief Create a String of the 3-letter day of the week bitmap
|
||||
// e.g. 0b0000101 is "Sun | Tue"
|
||||
/// @param[in] daysBitmap The bitmap representing days of week to represent
|
||||
/// e.g bit[0]=Sunday, bit[1]=Monday, ...
|
||||
/// @param[in] offset Days to offset by.
|
||||
/// e.g. For different day starting the week.
|
||||
/// @return String representation.
|
||||
String daysBitmaskToString(uint8_t daysBitmap, uint8_t offset) {
|
||||
String result = "";
|
||||
result.reserve(27); // Sun|Mon|Tue|Wed|Thu|Fri|Sat
|
||||
|
||||
for (uint8_t i = 0; i < 7; ++i) {
|
||||
if (((daysBitmap >> i) & 0b1) == 0b1) {
|
||||
if (result.length() > 0) {
|
||||
result += "|";
|
||||
}
|
||||
result += irutils::dayToString(i, offset);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Escape any special HTML (unsafe) characters in a string. e.g. anti-XSS.
|
||||
/// @param[in] unescaped A String containing text to make HTML safe.
|
||||
/// @return A string that is HTML safe.
|
||||
|
|
|
@ -60,16 +60,19 @@ namespace irutils {
|
|||
String addLabeledString(const String value, const String label,
|
||||
const bool precomma = true);
|
||||
String addTempToString(const uint16_t degrees, const bool celsius = true,
|
||||
const bool precomma = true);
|
||||
const bool precomma = true,
|
||||
const bool isSensorTemp = false);
|
||||
String addTempFloatToString(const float degrees, const bool celsius = true,
|
||||
const bool precomma = true);
|
||||
const bool precomma = true,
|
||||
const bool isSensorTemp = false);
|
||||
String addModeToString(const uint8_t mode, const uint8_t automatic,
|
||||
const uint8_t cool, const uint8_t heat,
|
||||
const uint8_t dry, const uint8_t fan);
|
||||
String addFanToString(const uint8_t speed, const uint8_t high,
|
||||
const uint8_t low, const uint8_t automatic,
|
||||
const uint8_t quiet, const uint8_t medium,
|
||||
const uint8_t maximum = 0xFF);
|
||||
const uint8_t maximum = 0xFF,
|
||||
const uint8_t medium_high = 0xFF);
|
||||
String addSwingHToString(const uint8_t position, const uint8_t automatic,
|
||||
const uint8_t maxleft, const uint8_t left,
|
||||
const uint8_t middle,
|
||||
|
@ -87,6 +90,19 @@ namespace irutils {
|
|||
const uint8_t breeze, const uint8_t circulate);
|
||||
String addDayToString(const uint8_t day_of_week, const int8_t offset = 0,
|
||||
const bool precomma = true);
|
||||
String addTimerModeToString(const uint8_t timerType, const uint8_t noTimer,
|
||||
const uint8_t delayTimer,
|
||||
const uint8_t schedule1 = 0xFF,
|
||||
const uint8_t schedule2 = 0xFF,
|
||||
const uint8_t schedule3 = 0xFF,
|
||||
const bool precomma = true);
|
||||
String irCommandTypeToString(uint8_t commandType, uint8_t acControlCmd,
|
||||
uint8_t iFeelReportCmd = 0xFF,
|
||||
uint8_t timerCmd = 0xFF,
|
||||
uint8_t configCmd = 0xFF);
|
||||
String dayToString(const uint8_t day_of_week, const int8_t offset = 0);
|
||||
String daysBitmaskToString(uint8_t daysBitmap, uint8_t offset = 0);
|
||||
String channelToString(const uint8_t channel);
|
||||
String htmlEscape(const String unescaped);
|
||||
String msToString(uint32_t const msecs);
|
||||
String minsToString(const uint16_t mins);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,13 +1,18 @@
|
|||
// Copyright 2017 Schmolders
|
||||
// Copyright 2022 crankyoldgit
|
||||
// Copyright 2022 Mateusz Bronk (mbronk)
|
||||
/// @file
|
||||
/// @brief Support for Argo Ulisse 13 DCI Mobile Split ACs.
|
||||
|
||||
// Supports:
|
||||
// Brand: Argo, Model: Ulisse 13 DCI Mobile Split A/C
|
||||
// Brand: Argo, Model: Ulisse 13 DCI Mobile Split A/C [WREM2 remote]
|
||||
// Brand: Argo, Model: Ulisse Eco Mobile Split A/C (Wifi) [WREM3 remote]
|
||||
|
||||
#ifndef IR_ARGO_H_
|
||||
#define IR_ARGO_H_
|
||||
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#ifndef UNIT_TEST
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
|
@ -20,14 +25,14 @@
|
|||
|
||||
// ARGO Ulisse DCI
|
||||
|
||||
/// Native representation of a Argo A/C message.
|
||||
/// Native representation of a Argo A/C message for WREM-2 remote.
|
||||
union ArgoProtocol {
|
||||
uint8_t raw[kArgoStateLength]; ///< The state in native IR code form
|
||||
struct {
|
||||
// Byte 0
|
||||
uint64_t :8; // Typically 0b00110101
|
||||
uint64_t Pre1 :8; // Typically 0b00110101
|
||||
// Byte 1
|
||||
uint64_t :8; // Typically 0b10101111
|
||||
uint64_t Pre2 :8; // Typically 0b10101111
|
||||
// Byte 2~4
|
||||
uint64_t :3;
|
||||
uint64_t Mode :3;
|
||||
|
@ -57,17 +62,143 @@ union ArgoProtocol {
|
|||
uint32_t :1; // const 0
|
||||
uint32_t iFeel :1;
|
||||
// Byte 10~11
|
||||
uint32_t :2; // const 01
|
||||
uint32_t Post :2;
|
||||
uint32_t Sum :8; // straddle byte 10 and 11
|
||||
uint32_t :6;
|
||||
};
|
||||
struct {
|
||||
// Byte 0-1
|
||||
uint8_t :8;
|
||||
uint8_t :8;
|
||||
// Byte 2-3
|
||||
uint8_t CheckHi :3;
|
||||
uint8_t SensorT :5;
|
||||
uint8_t Fixed :3; // Typically 0b011
|
||||
uint8_t CheckLo :5;
|
||||
};
|
||||
};
|
||||
|
||||
// Constants. Store MSB left.
|
||||
/// Native representation of A/C IR message for WREM-3 remote
|
||||
/// @note The remote sends 4 different IR command types, varying in length
|
||||
/// and methods of checksum calculation
|
||||
/// - [0b00] Regular A/C command (change operation mode) - 6-byte
|
||||
/// - [0b01] iFeel Temperature report - 2-byte
|
||||
/// - [0b10] Timer command - 9-byte
|
||||
/// - [0b11] Config command - 4-byte
|
||||
/// @note The 1st 2 structures are unnamed for compat. with @c ArgoProtocol
|
||||
/// 1st byte definition is a header common across all commands though
|
||||
union ArgoProtocolWREM3 {
|
||||
uint8_t raw[kArgoStateLength]; ///< The state in native IR code form
|
||||
struct {
|
||||
// Byte 0 (same definition across the union)
|
||||
uint8_t Pre1 :4; /// Preamble: 0b1011 @ref kArgoWrem3Preamble
|
||||
uint8_t IrChannel :2; /// 0..3 range
|
||||
uint8_t IrCommandType :2; /// @ref argoIrMessageType_t
|
||||
// Byte 1
|
||||
uint8_t RoomTemp :5; // in Celsius, range: 4..35 (offset by -4[*C])
|
||||
uint8_t Mode :3; /// @ref argoMode_t
|
||||
// Byte 2
|
||||
uint8_t Temp :5; // in Celsius, range: 10..32 (offset by -4[*C])
|
||||
uint8_t Fan :3; /// @ref argoFan_t
|
||||
// Byte3
|
||||
uint8_t Flap :3; /// SwingV @ref argoFlap_t
|
||||
uint8_t Power :1;
|
||||
uint8_t iFeel :1;
|
||||
uint8_t Night :1;
|
||||
uint8_t Eco :1;
|
||||
uint8_t Max :1; ///< a.k.a. Turbo
|
||||
// Byte4
|
||||
uint8_t Filter :1;
|
||||
uint8_t Light :1;
|
||||
uint8_t Post1 :6; /// Unknown, always 0b110000 (TempScale?)
|
||||
// Byte5
|
||||
uint8_t Sum :8; /// Checksum
|
||||
};
|
||||
struct {
|
||||
// Byte 0 (same definition across the union)
|
||||
uint8_t :8; // {Pre1 | IrChannel | IrCommandType}
|
||||
// Byte 1
|
||||
uint8_t SensorT :5; // in Celsius, range: 4..35 (offset by -4[*C])
|
||||
uint8_t CheckHi :3; // Checksum (short)
|
||||
};
|
||||
struct Timer {
|
||||
// Byte 0 (same definition across the union)
|
||||
uint8_t : 8; // {Pre1 | IrChannel | IrCommandType}
|
||||
// Byte 1
|
||||
uint8_t IsOn : 1;
|
||||
uint8_t TimerType : 3;
|
||||
uint8_t CurrentTimeLo : 4;
|
||||
// Byte 2
|
||||
uint8_t CurrentTimeHi : 7;
|
||||
uint8_t CurrentWeekdayLo : 1;
|
||||
// Byte 3
|
||||
uint8_t CurrentWeekdayHi : 2;
|
||||
uint8_t DelayTimeLo : 6;
|
||||
// Byte 4
|
||||
uint8_t DelayTimeHi : 5;
|
||||
uint8_t TimerStartLo : 3;
|
||||
// Byte 5
|
||||
uint8_t TimerStartHi : 8;
|
||||
// Byte 6
|
||||
uint8_t TimerEndLo : 8;
|
||||
// Byte 7
|
||||
uint8_t TimerEndHi : 3;
|
||||
uint8_t TimerActiveDaysLo : 5; // Bitmap (LSBit is Sunday)
|
||||
// Byte 8
|
||||
uint8_t TimerActiveDaysHi : 2; // Bitmap (LSBit is Sunday)
|
||||
uint8_t Post1 : 1; // Unknown, always 1
|
||||
uint8_t Checksum : 5;
|
||||
} timer;
|
||||
struct Config {
|
||||
uint8_t :8; // Byte 0 {Pre1 | IrChannel | IrCommandType}
|
||||
uint8_t Key :8; // Byte 1
|
||||
uint8_t Value :8; // Byte 2
|
||||
uint8_t Checksum :8; // Byte 3
|
||||
} config;
|
||||
};
|
||||
|
||||
const uint8_t kArgoHeatBit = 0b00100000;
|
||||
// Constants (WREM-2). Store MSB left.
|
||||
const uint8_t kArgoHeatBit = 0b00100000;
|
||||
const uint8_t kArgoPreamble1 = 0b10101100;
|
||||
const uint8_t kArgoPreamble2 = 0b11110101;
|
||||
const uint8_t kArgoPost = 0b00000010;
|
||||
|
||||
// Mode 0b00111000
|
||||
// Constants (generic)
|
||||
const uint16_t kArgoFrequency = 38000; // Hz
|
||||
// Temp
|
||||
const uint8_t kArgoTempDelta = 4;
|
||||
const uint8_t kArgoMaxRoomTemp = 35; // Celsius
|
||||
const uint8_t kArgoMinTemp = 10; // Celsius delta +4
|
||||
const uint8_t kArgoMaxTemp = 32; // Celsius
|
||||
const uint8_t kArgoMaxChannel = 3;
|
||||
|
||||
|
||||
/// @brief IR message type (determines the payload part of IR command)
|
||||
/// @note Raw values match WREM-3 protocol, but the enum is used in generic
|
||||
/// context
|
||||
/// @note WREM-3 remote supports all commands separately, whereas
|
||||
/// WREM-2 (allegedly) only has the @c AC_CONTROL and @c IFEEL_TEMP_REPORT
|
||||
/// (timers are part of @c AC_CONTROL command), and there's no config.
|
||||
enum class argoIrMessageType_t : uint8_t {
|
||||
AC_CONTROL = 0b00,
|
||||
IFEEL_TEMP_REPORT = 0b01,
|
||||
TIMER_COMMAND = 0b10, // WREM-3 only (WREM-2 has it under AC_CONTROL)
|
||||
CONFIG_PARAM_SET = 0b11 // WREM-3 only
|
||||
};
|
||||
|
||||
/// @brief A/C operation mode
|
||||
/// @note Raw values match WREM-3 protocol, but the enum is used in generic
|
||||
/// context
|
||||
enum class argoMode_t : uint8_t {
|
||||
COOL = 0b001,
|
||||
DRY = 0b010,
|
||||
HEAT = 0b011,
|
||||
FAN = 0b100,
|
||||
AUTO = 0b101
|
||||
};
|
||||
|
||||
// Raw mode definitions for WREM-2 remote
|
||||
// (not wraped into a ns nor enum for backwards-compat.)
|
||||
const uint8_t kArgoCool = 0b000;
|
||||
const uint8_t kArgoDry = 0b001;
|
||||
const uint8_t kArgoAuto = 0b010;
|
||||
|
@ -77,19 +208,42 @@ const uint8_t kArgoHeatAuto = 0b101;
|
|||
// ?no idea what mode that is
|
||||
const uint8_t kArgoHeatBlink = 0b110;
|
||||
|
||||
// Fan 0b00011000
|
||||
/// @brief Fan speed
|
||||
/// @note Raw values match WREM-3 protocol, but the enum is used in generic
|
||||
/// context
|
||||
enum class argoFan_t : uint8_t {
|
||||
FAN_AUTO = 0b000,
|
||||
FAN_LOWEST = 0b001,
|
||||
FAN_LOWER = 0b010,
|
||||
FAN_LOW = 0b011,
|
||||
FAN_MEDIUM = 0b100,
|
||||
FAN_HIGH = 0b101,
|
||||
FAN_HIGHEST = 0b110
|
||||
};
|
||||
|
||||
// Raw fan speed definitions for WREM-2 remote
|
||||
// (not wraped into a ns nor enum for backwards-compat.)
|
||||
const uint8_t kArgoFanAuto = 0; // 0b00
|
||||
const uint8_t kArgoFan1 = 1; // 0b01
|
||||
const uint8_t kArgoFan2 = 2; // 0b10
|
||||
const uint8_t kArgoFan3 = 3; // 0b11
|
||||
|
||||
// Temp
|
||||
const uint8_t kArgoTempDelta = 4;
|
||||
const uint8_t kArgoMaxRoomTemp = 35; // Celsius
|
||||
const uint8_t kArgoMinTemp = 10; // Celsius delta +4
|
||||
const uint8_t kArgoMaxTemp = 32; // Celsius
|
||||
/// @brief Flap position (swing-V)
|
||||
/// @note Raw values match WREM-3 protocol, but the enum is used in generic
|
||||
/// context
|
||||
enum class argoFlap_t : uint8_t {
|
||||
FLAP_AUTO = 0,
|
||||
FLAP_1 = 1, // Highest
|
||||
FLAP_2 = 2,
|
||||
FLAP_3 = 3,
|
||||
FLAP_4 = 4,
|
||||
FLAP_5 = 5,
|
||||
FLAP_6 = 6, // Lowest
|
||||
FLAP_FULL = 7
|
||||
};
|
||||
|
||||
// Flap/SwingV
|
||||
// Raw Flap/SwingV definitions for WREM-2 remote
|
||||
// (not wraped into a ns nor enum for backwards-compat.)
|
||||
const uint8_t kArgoFlapAuto = 0;
|
||||
const uint8_t kArgoFlap1 = 1;
|
||||
const uint8_t kArgoFlap2 = 2;
|
||||
|
@ -123,22 +277,61 @@ const uint8_t kArgoFlapFull = 7;
|
|||
#define ARGO_FLAP_FULL kArgoFlapFull
|
||||
|
||||
|
||||
/// Class for handling detailed Argo A/C messages.
|
||||
class IRArgoAC {
|
||||
/// @brief Timer type to set (for @c argoIrMessageType_t::TIMER_COMMAND)
|
||||
/// @note Raw values match WREM-3 protocol
|
||||
enum class argoTimerType_t : uint8_t {
|
||||
NO_TIMER = 0b000,
|
||||
DELAY_TIMER = 0b001,
|
||||
SCHEDULE_TIMER_1 = 0b010,
|
||||
SCHEDULE_TIMER_2 = 0b011,
|
||||
SCHEDULE_TIMER_3 = 0b100
|
||||
};
|
||||
|
||||
/// @brief Day type to set (for @c argoIrMessageType_t::TIMER_COMMAND)
|
||||
/// @note Raw values match WREM-3 protocol
|
||||
enum class argoWeekday : uint8_t {
|
||||
SUNDAY = 0b000,
|
||||
MONDAY = 0b001,
|
||||
TUESDAY = 0b010,
|
||||
WEDNESDAY = 0b011,
|
||||
THURSDAY = 0b100,
|
||||
FRIDAY = 0b101,
|
||||
SATURDAY = 0b110
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// @brief Base class for handling *common* support for Argo remote protocols
|
||||
/// (functionality is shared across WREM-2 and WREM-3 IR protocols)
|
||||
/// @note This class uses static polymorphism and full template specializations
|
||||
/// when required, to avoid a performance penalty of doing v-table lookup.
|
||||
/// 2 instantiations are forced in impl. file: for @c ArgoProtocol and
|
||||
/// @c ArgoProtocolWREM3
|
||||
/// @note This class is abstract (though does not declare a pure-virtual fn.
|
||||
/// for abovementioned reasons), and instead declares protected c-tor
|
||||
/// @tparam ARGO_PROTOCOL_T The Raw device protocol/message used
|
||||
template <typename ARGO_PROTOCOL_T>
|
||||
class IRArgoACBase {
|
||||
#ifndef UNIT_TEST // A less cloggy way of expressing FRIEND_TEST(...)
|
||||
|
||||
protected:
|
||||
#else
|
||||
|
||||
public:
|
||||
explicit IRArgoAC(const uint16_t pin, const bool inverted = false,
|
||||
#endif
|
||||
explicit IRArgoACBase(const uint16_t pin, const bool inverted = false,
|
||||
const bool use_modulation = true);
|
||||
|
||||
public:
|
||||
#if SEND_ARGO
|
||||
void send(const uint16_t repeat = kArgoDefaultRepeat);
|
||||
void sendSensorTemp(const uint8_t temp,
|
||||
const uint16_t repeat = kArgoDefaultRepeat);
|
||||
/// Run the calibration to calculate uSec timing offsets for this platform.
|
||||
/// @return The uSec timing offset needed per modulation of the IR Led.
|
||||
/// @note This will produce a 65ms IR signal pulse at 38kHz.
|
||||
/// Only ever needs to be run once per object instantiation, if at all.
|
||||
int8_t calibrate(void) { return _irsend.calibrate(); }
|
||||
#endif // SEND_ARGO
|
||||
|
||||
void begin(void);
|
||||
void on(void);
|
||||
void off(void);
|
||||
|
@ -149,14 +342,20 @@ class IRArgoAC {
|
|||
void setTemp(const uint8_t degrees);
|
||||
uint8_t getTemp(void) const;
|
||||
|
||||
void setFan(const uint8_t fan);
|
||||
uint8_t getFan(void) const;
|
||||
void setSensorTemp(const uint8_t degrees);
|
||||
uint8_t getSensorTemp(void) const;
|
||||
|
||||
void setFlap(const uint8_t flap);
|
||||
uint8_t getFlap(void) const;
|
||||
void setFan(const argoFan_t fan);
|
||||
void setFanEx(const argoFan_t fan) { setFan(fan); }
|
||||
argoFan_t getFanEx(void) const; ///< `-Ex` for backw. compat w/ @c IRArgoAC
|
||||
|
||||
void setMode(const uint8_t mode);
|
||||
uint8_t getMode(void) const;
|
||||
void setFlap(const argoFlap_t flap);
|
||||
void setFlapEx(const argoFlap_t flap) { setFlap(flap); }
|
||||
argoFlap_t getFlapEx(void) const; ///< `-Ex` for backw. compat w/ @c IRArgoAC
|
||||
|
||||
void setMode(const argoMode_t mode);
|
||||
void setModeEx(const argoMode_t mode) { setMode(mode); }
|
||||
argoMode_t getModeEx(void) const; ///< `-Ex` for backw. compat w/ @c IRArgoAC
|
||||
|
||||
void setMax(const bool on);
|
||||
bool getMax(void) const;
|
||||
|
@ -167,41 +366,156 @@ class IRArgoAC {
|
|||
void setiFeel(const bool on);
|
||||
bool getiFeel(void) const;
|
||||
|
||||
void setTime(void);
|
||||
void setRoomTemp(const uint8_t degrees);
|
||||
uint8_t getRoomTemp(void) const;
|
||||
void setMessageType(const argoIrMessageType_t msgType);
|
||||
argoIrMessageType_t getMessageType(void) const;
|
||||
static argoIrMessageType_t getMessageType(const uint8_t state[],
|
||||
const uint16_t length);
|
||||
|
||||
uint8_t* getRaw(void);
|
||||
void setRaw(const uint8_t state[]);
|
||||
static uint8_t calcChecksum(const uint8_t state[],
|
||||
const uint16_t length = kArgoStateLength);
|
||||
static bool validChecksum(const uint8_t state[],
|
||||
const uint16_t length = kArgoStateLength);
|
||||
static uint8_t convertMode(const stdAc::opmode_t mode);
|
||||
static uint8_t convertFan(const stdAc::fanspeed_t speed);
|
||||
static uint8_t convertSwingV(const stdAc::swingv_t position);
|
||||
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;
|
||||
uint16_t getRawByteLength() const;
|
||||
static uint16_t getStateLengthForIrMsgType(argoIrMessageType_t type);
|
||||
void setRaw(const uint8_t state[], const uint16_t length);
|
||||
|
||||
static bool validChecksum(const uint8_t state[], const uint16_t length);
|
||||
|
||||
static argoMode_t convertMode(const stdAc::opmode_t mode);
|
||||
static argoFan_t convertFan(const stdAc::fanspeed_t speed);
|
||||
static argoFlap_t convertSwingV(const stdAc::swingv_t position);
|
||||
static argoIrMessageType_t convertCommand(const stdAc::ac_command_t command);
|
||||
|
||||
protected:
|
||||
void _stateReset(ARGO_PROTOCOL_T *state, argoIrMessageType_t messageType
|
||||
= argoIrMessageType_t::AC_CONTROL);
|
||||
void stateReset(argoIrMessageType_t messageType
|
||||
= argoIrMessageType_t::AC_CONTROL);
|
||||
void _checksum(ARGO_PROTOCOL_T *state);
|
||||
void checksum(void);
|
||||
static uint16_t getRawByteLength(const ARGO_PROTOCOL_T& raw,
|
||||
argoIrMessageType_t messageTypeHint = argoIrMessageType_t::AC_CONTROL);
|
||||
static uint8_t calcChecksum(const uint8_t state[], const uint16_t length);
|
||||
static uint8_t getChecksum(const uint8_t state[], const uint16_t length);
|
||||
|
||||
static stdAc::opmode_t toCommonMode(const argoMode_t mode);
|
||||
static stdAc::fanspeed_t toCommonFanSpeed(const argoFan_t speed);
|
||||
static stdAc::swingv_t toCommonSwingV(const uint8_t position);
|
||||
static stdAc::ac_command_t toCommonCommand(const argoIrMessageType_t command);
|
||||
|
||||
// Attributes
|
||||
ARGO_PROTOCOL_T _; ///< The raw protocol data
|
||||
uint16_t _length = kArgoStateLength;
|
||||
argoIrMessageType_t _messageType = argoIrMessageType_t::AC_CONTROL;
|
||||
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
private:
|
||||
protected:
|
||||
IRsend _irsend; ///< instance of the IR send class
|
||||
#else
|
||||
|
||||
public:
|
||||
/// @cond IGNORE
|
||||
IRsendTest _irsend; ///< instance of the testing IR send class
|
||||
/// @endcond
|
||||
#endif
|
||||
// # of bytes per command
|
||||
ArgoProtocol _;
|
||||
void stateReset(void);
|
||||
void checksum(void);
|
||||
};
|
||||
|
||||
// Attributes
|
||||
uint8_t flap_mode;
|
||||
uint8_t heat_mode;
|
||||
uint8_t cool_mode;
|
||||
/// @brief Supports Argo A/C SAC-WREM2 IR remote protocol
|
||||
class IRArgoAC : public IRArgoACBase<ArgoProtocol> {
|
||||
public:
|
||||
explicit IRArgoAC(const uint16_t pin, const bool inverted = false,
|
||||
const bool use_modulation = true);
|
||||
|
||||
#if SEND_ARGO
|
||||
void sendSensorTemp(const uint8_t degrees,
|
||||
const uint16_t repeat = kArgoDefaultRepeat);
|
||||
#endif // SEND_ARGO
|
||||
|
||||
String toString(void) const;
|
||||
stdAc::state_t toCommon(void) const;
|
||||
|
||||
using IRArgoACBase<ArgoProtocol>::setMode;
|
||||
void setMode(const uint8_t mode); /// @deprecated, for backwards-compat.
|
||||
uint8_t getMode(void) const; /// @deprecated, for backwards-compat.
|
||||
|
||||
using IRArgoACBase<ArgoProtocol>::setFan;
|
||||
void setFan(const uint8_t fan); /// @deprecated, for backwards-compat.
|
||||
uint8_t getFan(void) const; /// @deprecated, for backwards-compat.
|
||||
|
||||
using IRArgoACBase<ArgoProtocol>::setFlap;
|
||||
void setFlap(const uint8_t flap); /// @deprecated, for backwards-compat.
|
||||
uint8_t getFlap(void) const; /// @deprecated, for backwards-compat.
|
||||
};
|
||||
|
||||
/// @brief Supports Argo A/C SAC-WREM3 IR remote protocol
|
||||
class IRArgoAC_WREM3 : public IRArgoACBase<ArgoProtocolWREM3> {
|
||||
public:
|
||||
explicit IRArgoAC_WREM3(const uint16_t pin, const bool inverted = false,
|
||||
const bool use_modulation = true);
|
||||
|
||||
#if SEND_ARGO
|
||||
void sendSensorTemp(const uint8_t degrees,
|
||||
const uint16_t repeat = kArgoDefaultRepeat);
|
||||
#endif // SEND_ARGO
|
||||
|
||||
argo_ac_remote_model_t getModel(void) const;
|
||||
|
||||
|
||||
argoFan_t getFan(void) const;
|
||||
argoFlap_t getFlap(void) const;
|
||||
argoMode_t getMode(void) const;
|
||||
|
||||
void setEco(const bool on);
|
||||
bool getEco(void) const;
|
||||
|
||||
void setFilter(const bool on);
|
||||
bool getFilter(void) const;
|
||||
|
||||
void setLight(const bool on);
|
||||
bool getLight(void) const;
|
||||
|
||||
void setChannel(const uint8_t channel);
|
||||
uint8_t getChannel(void) const;
|
||||
|
||||
void setConfigEntry(const uint8_t paramId, const uint8_t value);
|
||||
std::pair<uint8_t, uint8_t> getConfigEntry(void) const;
|
||||
|
||||
void setCurrentTimeMinutes(uint16_t currentTimeMinutes);
|
||||
uint16_t getCurrentTimeMinutes(void) const;
|
||||
|
||||
void setCurrentDayOfWeek(argoWeekday dayOfWeek);
|
||||
argoWeekday getCurrentDayOfWeek(void) const;
|
||||
|
||||
void setTimerType(const argoTimerType_t timerType);
|
||||
argoTimerType_t getTimerType(void) const;
|
||||
|
||||
void setDelayTimerMinutes(const uint16_t delayMinutes);
|
||||
uint16_t getDelayTimerMinutes(void) const;
|
||||
|
||||
void setScheduleTimerStartMinutes(const uint16_t startTimeMinutes);
|
||||
uint16_t getScheduleTimerStartMinutes(void) const;
|
||||
// uint16_t getTimerXStartMinutes(void) const
|
||||
|
||||
void setScheduleTimerStopMinutes(const uint16_t stopTimeMinutes);
|
||||
uint16_t getScheduleTimerStopMinutes(void) const;
|
||||
// uint16_t getTimerXStopMinutes(void) const;
|
||||
|
||||
|
||||
void setScheduleTimerActiveDays(const std::set<argoWeekday>& days);
|
||||
std::set<argoWeekday> getScheduleTimerActiveDays(void) const;
|
||||
uint8_t getTimerActiveDaysBitmap(void) const;
|
||||
|
||||
using IRArgoACBase<ArgoProtocolWREM3>::getMessageType;
|
||||
static argoIrMessageType_t getMessageType(const ArgoProtocolWREM3& raw);
|
||||
|
||||
String toString(void) const;
|
||||
stdAc::state_t toCommon(void) const;
|
||||
|
||||
static bool hasValidPreamble(const uint8_t state[], const uint16_t length);
|
||||
|
||||
public:
|
||||
#if DECODE_ARGO
|
||||
static bool isValidWrem3Message(const uint8_t state[], const uint16_t nbits,
|
||||
bool verifyChecksum = true);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // IR_ARGO_H_
|
||||
|
|
|
@ -46,6 +46,15 @@ const uint16_t kCarrierAc64OneSpace = 1736;
|
|||
const uint16_t kCarrierAc64ZeroSpace = 615;
|
||||
const uint32_t kCarrierAc64Gap = kDefaultMessageGap; // A guess.
|
||||
|
||||
//< @see: https://github.com/crankyoldgit/IRremoteESP8266/issues/1943#issue-1519570772
|
||||
const uint16_t kCarrierAc84HdrMark = 5850;
|
||||
const uint16_t kCarrierAc84Zero = 1175;
|
||||
const uint16_t kCarrierAc84One = 430;
|
||||
const uint16_t kCarrierAc84HdrSpace = kCarrierAc84Zero;
|
||||
const uint32_t kCarrierAc84Gap = kDefaultMessageGap; // A guess.
|
||||
const uint8_t kCarrierAc84ExtraBits = 4;
|
||||
const uint8_t kCarrierAc84ExtraTolerance = 5;
|
||||
|
||||
const uint16_t kCarrierAc128HdrMark = 4600;
|
||||
const uint16_t kCarrierAc128HdrSpace = 2600;
|
||||
const uint16_t kCarrierAc128Hdr2Mark = 9300;
|
||||
|
@ -645,3 +654,94 @@ bool IRrecv::decodeCarrierAC128(decode_results *results, uint16_t offset,
|
|||
return true;
|
||||
}
|
||||
#endif // DECODE_CARRIER_AC128
|
||||
|
||||
#if SEND_CARRIER_AC84
|
||||
/// Send a Carroer A/C 84 Bit formatted message.
|
||||
/// Status: BETA / Untested but probably works.
|
||||
/// @param[in] data The message to be sent.
|
||||
/// @param[in] nbytes The byte size of the message being sent.
|
||||
/// @param[in] repeat The number of times the command is to be repeated.
|
||||
void IRsend::sendCarrierAC84(const uint8_t data[], const uint16_t nbytes,
|
||||
const uint16_t repeat) {
|
||||
// Protocol uses a constant bit time encoding.
|
||||
for (uint16_t r = 0; r <= repeat; r++) {
|
||||
if (nbytes) {
|
||||
// The least significant `kCarrierAc84ExtraBits` bits of the first byte
|
||||
sendGeneric(kCarrierAc84HdrMark, kCarrierAc84HdrSpace, // Header
|
||||
kCarrierAc84Zero, kCarrierAc84One, // Data
|
||||
kCarrierAc84One, kCarrierAc84Zero,
|
||||
0, 0, // No footer
|
||||
GETBITS64(data[0], 0, kCarrierAc84ExtraBits),
|
||||
kCarrierAc84ExtraBits,
|
||||
38000, false, 0, 33);
|
||||
// The rest of the data.
|
||||
sendGeneric(0, 0, // No Header
|
||||
kCarrierAc84Zero, kCarrierAc84One, // Data
|
||||
kCarrierAc84One, kCarrierAc84Zero,
|
||||
kCarrierAc84Zero, kDefaultMessageGap, // Footer
|
||||
data + 1, nbytes - 1, 38000, false, 0, 33);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // SEND_CARRIER_AC84
|
||||
|
||||
#if DECODE_CARRIER_AC84
|
||||
/// Decode the supplied Carroer A/C 84 Bit formatted message.
|
||||
/// Status: STABLE / Confirmed Working.
|
||||
/// @param[in,out] results Ptr to the data to decode & where to store the decode
|
||||
/// 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 A boolean. True if it can decode it, false if it can't.
|
||||
bool IRrecv::decodeCarrierAC84(decode_results *results, uint16_t offset,
|
||||
const uint16_t nbits, const bool strict) {
|
||||
// Check if we have enough data to even possibly match.
|
||||
if (results->rawlen < 2 * nbits + kHeader + kFooter - 1 + offset)
|
||||
return false; // Can't possibly be a valid Carrier message.
|
||||
// Compliance check.
|
||||
if (strict && nbits != kCarrierAc84Bits) return false;
|
||||
|
||||
// This decoder expects to decode an unusual number of bits. Check before we
|
||||
// start.
|
||||
if (nbits % 8 != kCarrierAc84ExtraBits) return false;
|
||||
|
||||
uint64_t data = 0;
|
||||
uint16_t used = 0;
|
||||
|
||||
// Header + Data (kCarrierAc84ExtraBits only)
|
||||
used = matchGenericConstBitTime(results->rawbuf + offset, &data,
|
||||
results->rawlen - offset,
|
||||
kCarrierAc84ExtraBits,
|
||||
// Header (None)
|
||||
kCarrierAc84HdrMark, kCarrierAc84HdrSpace,
|
||||
// Data
|
||||
kCarrierAc84Zero, kCarrierAc84One,
|
||||
// No Footer
|
||||
0, 0,
|
||||
false,
|
||||
_tolerance + kCarrierAc84ExtraTolerance,
|
||||
kMarkExcess, false);
|
||||
if (!used) return false;
|
||||
// Stuff the captured data so far into the first byte of the state.
|
||||
*results->state = data;
|
||||
offset += used;
|
||||
// Capture the rest of the data as normal as we should be on a byte boundary.
|
||||
// Data + Footer
|
||||
if (!matchGeneric(results->rawbuf + offset, results->state + 1,
|
||||
results->rawlen - offset, nbits - kCarrierAc84ExtraBits,
|
||||
0, 0, // No Header expected.
|
||||
kCarrierAc84Zero, kCarrierAc84One, // Data
|
||||
kCarrierAc84One, kCarrierAc84Zero,
|
||||
kCarrierAc84Zero, kDefaultMessageGap, true,
|
||||
_tolerance + kCarrierAc84ExtraTolerance,
|
||||
kMarkExcess, false)) return false;
|
||||
|
||||
// Success
|
||||
results->decode_type = decode_type_t::CARRIER_AC84;
|
||||
results->bits = nbits;
|
||||
results->repeat = false;
|
||||
return true;
|
||||
}
|
||||
#endif // DECODE_CARRIER_AC84
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1127
|
||||
/// @see https://docs.google.com/spreadsheets/d/1EZy78L0cn1KDIX1aKq2biptejFqCjD5HO3tLiRvXf48/edit#gid=0
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1797
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1943
|
||||
|
||||
// Supports:
|
||||
// Brand: Carrier/Surrey, Model: 42QG5A55970 remote
|
||||
|
@ -13,6 +14,8 @@
|
|||
// Brand: Carrier/Surrey, Model: 619EGX0220E0 A/C
|
||||
// Brand: Carrier/Surrey, Model: 53NGK009/012 Inverter
|
||||
// Brand: Carrier, Model: 40GKX0E2006 remote (CARRIER_AC128)
|
||||
// Brand: Carrier, Model: 3021203 RR03-S-Remote (CARRIER_AC84)
|
||||
// Brand: Carrier, Model: 342WM100CT A/C (CARRIER_AC84)
|
||||
|
||||
#ifndef IR_CARRIER_H_
|
||||
#define IR_CARRIER_H_
|
||||
|
|
|
@ -548,6 +548,8 @@ stdAc::state_t IRCoolixAC::toCommon(const stdAc::state_t *prev) const {
|
|||
// Back to "normal" stateful messages.
|
||||
result.mode = toCommonMode(getMode());
|
||||
result.degrees = getTemp();
|
||||
result.sensorTemperature = getSensorTemp();
|
||||
result.iFeel = getZoneFollow();
|
||||
result.fanspeed = toCommonFanSpeed(getFan());
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -165,6 +165,7 @@ class IRCoolixAC {
|
|||
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
|
||||
stdAc::state_t toCommon(const stdAc::state_t *prev = NULL) const;
|
||||
String toString(void) const;
|
||||
void setZoneFollow(const bool on);
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
private:
|
||||
|
@ -189,7 +190,6 @@ class IRCoolixAC {
|
|||
void setTempRaw(const uint8_t code);
|
||||
uint8_t getTempRaw(void) const;
|
||||
void setSensorTempRaw(const uint8_t code);
|
||||
void setZoneFollow(const bool on);
|
||||
bool isSpecialState(void) const;
|
||||
bool handleSpecialState(const uint32_t data);
|
||||
void updateAndSaveState(const uint32_t raw_state);
|
||||
|
|
|
@ -365,6 +365,7 @@ stdAc::state_t IREcoclimAc::toCommon(void) const {
|
|||
result.mode = toCommonMode(getMode());
|
||||
result.celsius = true;
|
||||
result.degrees = getTemp();
|
||||
result.sensorTemperature = getSensorTemp();
|
||||
result.fanspeed = toCommonFanSpeed(_.Fan);
|
||||
result.sleep = (getMode() == kEcoclimSleep) ? 0 : -1;
|
||||
result.clock = getClock();
|
||||
|
|
|
@ -365,6 +365,7 @@ stdAc::state_t IRElectraAc::toCommon(void) const {
|
|||
result.mode = toCommonMode(_.Mode);
|
||||
result.celsius = true;
|
||||
result.degrees = getTemp();
|
||||
result.sensorTemperature = getSensorTemp();
|
||||
result.fanspeed = toCommonFanSpeed(_.Fan);
|
||||
result.swingv = getSwingV() ? stdAc::swingv_t::kAuto
|
||||
: stdAc::swingv_t::kOff;
|
||||
|
@ -373,6 +374,7 @@ stdAc::state_t IRElectraAc::toCommon(void) const {
|
|||
result.light = getLightToggle();
|
||||
result.turbo = _.Turbo;
|
||||
result.clean = _.Clean;
|
||||
result.iFeel = getIFeel();
|
||||
// Not supported.
|
||||
result.model = -1; // No models used.
|
||||
result.quiet = false;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
// Brand: Centek, Model: SCT-65Q09 A/C
|
||||
// Brand: Centek, Model: YKR-P/002E remote
|
||||
// Brand: AEG, Model: Chillflex Pro AXP26U338CW A/C
|
||||
// Brand: Electrolux, Model: YKR-H/531E A/C
|
||||
|
||||
#ifndef IR_ELECTRA_H_
|
||||
#define IR_ELECTRA_H_
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2022 Mateusz Bronk (mbronk)
|
||||
/// @file
|
||||
/// @brief Support for the Gorenje cooker hood IR protocols.
|
||||
/// @see https://techfresh.pl/wp-content/uploads/2017/08/Gorenje-DKF-2600-MWT.pdf
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1887
|
||||
|
||||
// Supports:
|
||||
// Brand: Gorenje, Model: DKF 2600 MWT Cooker Hood
|
||||
|
||||
#include "IRrecv.h"
|
||||
#include "IRsend.h"
|
||||
#include "IRutils.h"
|
||||
|
||||
const uint32_t kGorenjeMinGap = 100000U; // 0.1s
|
||||
const uint16_t kGorenjeHdrMark = 0;
|
||||
const uint32_t kGorenjeHdrSpace = 0;
|
||||
const uint16_t kGorenjeBitMark = 1300;
|
||||
const uint32_t kGorenjeOneSpace = 5700;
|
||||
const uint32_t kGorenjeZeroSpace = 1700;
|
||||
const uint16_t kGorenjeFreq = 38000; // Hz
|
||||
const uint16_t kGorenjeTolerance = 7; // %
|
||||
|
||||
#if SEND_GORENJE
|
||||
/// Send a Gorenje Cooker Hood formatted message.
|
||||
/// Status: STABLE / Known working.
|
||||
/// @param[in] data containing the IR command to be sent.
|
||||
/// @param[in] nbits Nr. of bits of the message to send. usually kGorenjeBits
|
||||
/// @param[in] repeat Nr. of times the message is to be repeated.
|
||||
void IRsend::sendGorenje(const uint64_t data, const uint16_t nbits,
|
||||
const uint16_t repeat) {
|
||||
sendGeneric(kGorenjeHdrMark, kGorenjeHdrSpace,
|
||||
kGorenjeBitMark, kGorenjeOneSpace,
|
||||
kGorenjeBitMark, kGorenjeZeroSpace,
|
||||
kGorenjeBitMark, kGorenjeMinGap,
|
||||
data, nbits, kGorenjeFreq, true, repeat, kDutyDefault);
|
||||
}
|
||||
#endif // SEND_GORENJE
|
||||
|
||||
#if DECODE_GORENJE
|
||||
/// Decode the supplied Gorenje Cooker Hood message.
|
||||
/// Status: STABLE / Known working.
|
||||
/// @param[in,out] results Ptr to the data to decode & where to store the
|
||||
/// decoded 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 A boolean. True if it can decode it, false if it can't.
|
||||
bool IRrecv::decodeGorenje(decode_results *results, uint16_t offset,
|
||||
const uint16_t nbits, const bool strict) {
|
||||
if (strict && nbits != kGorenjeBits)
|
||||
return false; // We expect Gorenje to be a certain sized message.
|
||||
|
||||
uint64_t data = 0;
|
||||
if (!matchGeneric(results->rawbuf + offset, &data,
|
||||
results->rawlen - offset, nbits,
|
||||
kGorenjeHdrMark, kGorenjeHdrSpace,
|
||||
kGorenjeBitMark, kGorenjeOneSpace,
|
||||
kGorenjeBitMark, kGorenjeZeroSpace,
|
||||
kGorenjeBitMark, kGorenjeMinGap,
|
||||
true, kGorenjeTolerance)) return false;
|
||||
|
||||
// Matched!
|
||||
results->bits = nbits;
|
||||
results->value = data;
|
||||
results->decode_type = decode_type_t::GORENJE;
|
||||
results->command = 0;
|
||||
results->address = 0;
|
||||
return true;
|
||||
}
|
||||
#endif // DECODE_GORENJE
|
|
@ -591,6 +591,8 @@ stdAc::state_t IRGreeAC::toCommon(void) {
|
|||
result.mode = toCommonMode(_.Mode);
|
||||
result.celsius = !_.UseFahrenheit;
|
||||
result.degrees = getTemp();
|
||||
// no support for Sensor temp.
|
||||
result.iFeel = getIFeel();
|
||||
result.fanspeed = toCommonFanSpeed(_.Fan);
|
||||
if (_.SwingAuto)
|
||||
result.swingv = stdAc::swingv_t::kAuto;
|
||||
|
|
|
@ -679,6 +679,7 @@ stdAc::state_t IRMideaAC::toCommon(const stdAc::state_t *prev) {
|
|||
result.mode = toCommonMode(_.Mode);
|
||||
result.celsius = !_.useFahrenheit;
|
||||
result.degrees = getTemp(result.celsius);
|
||||
result.sensorTemperature = getSensorTemp(result.celsius);
|
||||
result.fanspeed = toCommonFanSpeed(_.Fan);
|
||||
result.sleep = _.Sleep ? 0 : -1;
|
||||
result.econo = getEconoToggle();
|
||||
|
|
|
@ -740,6 +740,7 @@ stdAc::state_t IRMirageAc::toCommon(void) const {
|
|||
result.mode = toCommonMode(_.Mode);
|
||||
result.celsius = true;
|
||||
result.degrees = getTemp();
|
||||
result.sensorTemperature = getSensorTemp();
|
||||
result.fanspeed = toCommonFanSpeed(getFan(), _model);
|
||||
result.swingv = toCommonSwingV(getSwingV());
|
||||
result.swingh = getSwingH() ? stdAc::swingh_t::kAuto : stdAc::swingh_t::kOff;
|
||||
|
@ -750,6 +751,7 @@ stdAc::state_t IRMirageAc::toCommon(void) const {
|
|||
result.sleep = getSleep() ? 0 : -1;
|
||||
result.quiet = getQuiet();
|
||||
result.clock = getClock() / 60;
|
||||
result.iFeel = getIFeel();
|
||||
// Not supported.
|
||||
result.econo = false;
|
||||
result.beep = false;
|
||||
|
@ -775,10 +777,14 @@ void IRMirageAc::fromCommon(const stdAc::state_t state) {
|
|||
setFilter(state.filter);
|
||||
// setClock() expects seconds, not minutes.
|
||||
setClock((state.clock > 0) ? state.clock * 60 : 0);
|
||||
setIFeel(state.iFeel);
|
||||
if (state.sensorTemperature != kNoTempValue) {
|
||||
setSensorTemp(state.celsius ? state.sensorTemperature
|
||||
: fahrenheitToCelsius(state.sensorTemperature));
|
||||
}
|
||||
// Non-common settings.
|
||||
setOnTimer(0);
|
||||
setOffTimer(0);
|
||||
setIFeel(false);
|
||||
}
|
||||
|
||||
/// Convert the internal state into a human readable string.
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
// Brand: Mitsubishi Electric, Model: MSZ-ZW4017S A/C (MITSUBISHI_AC)
|
||||
// Brand: Mitsubishi Electric, Model: MSZ-FHnnVE A/C (MITSUBISHI_AC)
|
||||
// Brand: Mitsubishi Electric, Model: RH151 remote (MITSUBISHI_AC)
|
||||
// Brand: Mitsubishi Electric, Model: PAR-FA32MA remote (MITSUBISHI136)
|
||||
|
||||
#ifndef IR_MITSUBISHI_H_
|
||||
#define IR_MITSUBISHI_H_
|
||||
|
|
|
@ -128,8 +128,15 @@ uint64_t IRsend::encodePanasonic(const uint16_t manufacturer,
|
|||
bool IRrecv::decodePanasonic(decode_results *results, uint16_t offset,
|
||||
const uint16_t nbits, const bool strict,
|
||||
const uint32_t manufacturer) {
|
||||
if (strict && nbits != kPanasonicBits)
|
||||
return false; // Request is out of spec.
|
||||
if (strict) { // Compliance checks
|
||||
switch (nbits) {
|
||||
case kPanasonic40Bits:
|
||||
case kPanasonicBits:
|
||||
break;
|
||||
default:
|
||||
return false; // Request is out of spec.
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t data = 0;
|
||||
|
||||
|
@ -147,8 +154,10 @@ bool IRrecv::decodePanasonic(decode_results *results, uint16_t offset,
|
|||
if (address != manufacturer) // Verify the Manufacturer code.
|
||||
return false;
|
||||
// Verify the checksum.
|
||||
uint8_t checksumOrig = data;
|
||||
uint8_t checksumCalc = (data >> 24) ^ (data >> 16) ^ (data >> 8);
|
||||
const uint8_t checksumOrig = data;
|
||||
uint8_t checksumCalc = (data >> 16) ^ (data >> 8);
|
||||
if (nbits != kPanasonic40Bits)
|
||||
checksumCalc ^= (data >> 24);
|
||||
if (checksumOrig != checksumCalc) return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -622,10 +622,12 @@ stdAc::state_t IRSanyoAc::toCommon(void) const {
|
|||
result.mode = toCommonMode(_.Mode);
|
||||
result.celsius = true;
|
||||
result.degrees = getTemp();
|
||||
result.sensorTemperature = getSensorTemp();
|
||||
result.fanspeed = toCommonFanSpeed(_.Fan);
|
||||
result.sleep = _.Sleep ? 0 : -1;
|
||||
result.swingv = toCommonSwingV(_.SwingV);
|
||||
result.beep = _.Beep;
|
||||
result.iFeel = !getSensor();
|
||||
// Not supported.
|
||||
result.swingh = stdAc::swingh_t::kOff;
|
||||
result.turbo = false;
|
||||
|
@ -762,13 +764,13 @@ void IRSanyoAc88::stateReset(void) {
|
|||
/// Set up hardware to be able to send a message.
|
||||
void IRSanyoAc88::begin(void) { _irsend.begin(); }
|
||||
|
||||
#if SEND_SANYO_AC
|
||||
#if SEND_SANYO_AC88
|
||||
/// Send the current internal state as IR messages.
|
||||
/// @param[in] repeat Nr. of times the message will be repeated.
|
||||
void IRSanyoAc88::send(const uint16_t repeat) {
|
||||
_irsend.sendSanyoAc88(getRaw(), kSanyoAc88StateLength, repeat);
|
||||
}
|
||||
#endif // SEND_SANYO_AC
|
||||
#endif // SEND_SANYO_AC88
|
||||
|
||||
/// Get a PTR to the internal state/code for this protocol with all integrity
|
||||
/// checks passing.
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2022 David Conran
|
||||
|
||||
/// @file
|
||||
/// @brief Support for WowWee RoboRapter protocol
|
||||
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues1938
|
||||
|
||||
// Supports:
|
||||
// Brand: WowWee, Model: RoboRapter-X
|
||||
|
||||
// WowWee RoboRapter-X messages
|
||||
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1938#issuecomment-1367968228
|
||||
//
|
||||
// Button Code
|
||||
// ====== =====
|
||||
// Left 0x180
|
||||
// Forward 0x186
|
||||
// Backward 0x187
|
||||
// Right 0x188
|
||||
// Stop 0x18E
|
||||
// Head Counterclockwise 0x191
|
||||
// Tail Left 0x192
|
||||
// Tail Right 0x193
|
||||
// Head Clockwise 0x194
|
||||
// Guard Mode 0x1B0
|
||||
// Roam 0x1B1
|
||||
// Cautious Mood 0x1B2
|
||||
// Playful Mood 0x1B3
|
||||
// Hunting Mood 0x1B4
|
||||
// Demo 0x1D0
|
||||
// Bite 0x1D1
|
||||
|
||||
#include <algorithm>
|
||||
#include "IRrecv.h"
|
||||
#include "IRsend.h"
|
||||
#include "IRutils.h"
|
||||
|
||||
// Constants
|
||||
const uint16_t kWowweeHdrMark = 6684;
|
||||
const uint16_t kWowweeHdrSpace = 723;
|
||||
const uint16_t kWowweeBitMark = 912;
|
||||
const uint16_t kWowweeOneSpace = 3259;
|
||||
const uint16_t kWowweeZeroSpace = kWowweeHdrSpace;
|
||||
const uint16_t kWowweeFreq = 38000; // Hz. (Just a guess)
|
||||
|
||||
|
||||
#if SEND_WOWWEE
|
||||
/// Send a WowWee formatted message.
|
||||
/// Status: STABLE / Confirmed working with real device.
|
||||
/// @param[in] data The message to be sent.
|
||||
/// @param[in] nbits The number of bits of message to be sent.
|
||||
/// @param[in] repeat The number of times the command is to be repeated.
|
||||
void IRsend::sendWowwee(uint64_t data, uint16_t nbits, uint16_t repeat) {
|
||||
sendGeneric(kWowweeHdrMark, kWowweeHdrSpace,
|
||||
kWowweeBitMark, kWowweeOneSpace,
|
||||
kWowweeBitMark, kWowweeZeroSpace,
|
||||
kWowweeBitMark, kDefaultMessageGap, data,
|
||||
nbits, kWowweeFreq, true, repeat, 33);
|
||||
}
|
||||
#endif // SEND_WOWWEE
|
||||
|
||||
#if DECODE_WOWWEE
|
||||
/// Decode the supplied WowWee message.
|
||||
/// Status: STABLE / Confirmed working with 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.
|
||||
bool IRrecv::decodeWowwee(decode_results *results, uint16_t offset,
|
||||
const uint16_t nbits, const bool strict) {
|
||||
if (strict && nbits != kWowweeBits)
|
||||
return false; // We expect Wowwee to be a certain sized message.
|
||||
|
||||
uint64_t data = 0;
|
||||
|
||||
// Match Header + Data + Footer
|
||||
if (!matchGeneric(results->rawbuf + offset, &data,
|
||||
results->rawlen - offset, nbits,
|
||||
kWowweeHdrMark, kWowweeHdrSpace,
|
||||
kWowweeBitMark, kWowweeOneSpace,
|
||||
kWowweeBitMark, kWowweeZeroSpace,
|
||||
kWowweeBitMark, kDefaultMessageGap, true)) return false;
|
||||
// Success
|
||||
results->bits = nbits;
|
||||
results->value = data;
|
||||
results->decode_type = WOWWEE;
|
||||
results->command = 0;
|
||||
results->address = 0;
|
||||
return true;
|
||||
}
|
||||
#endif // DECODE_WOWWEE
|
|
@ -115,7 +115,7 @@ using IRXmpUtils::adjustRepeat;
|
|||
|
||||
#if SEND_XMP
|
||||
/// Send a XMP packet.
|
||||
/// Status: Beta / Untested against a real device.
|
||||
/// Status: STABLE / Confirmed working against a real device.
|
||||
/// @param[in] data The message to be sent.
|
||||
/// @param[in] nbits The number of bits of message to be sent.
|
||||
/// @param[in] repeat The number of times the command is to be repeated.
|
||||
|
@ -150,7 +150,7 @@ void IRsend::sendXmp(const uint64_t data, const uint16_t nbits,
|
|||
|
||||
#if DECODE_XMP
|
||||
/// Decode the supplied XMP packet/message.
|
||||
/// Status: BETA / Probably works.
|
||||
/// Status: STABLE / Confirmed working against 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.
|
||||
|
|
|
@ -0,0 +1,357 @@
|
|||
// Copyright 2022 Daniele Gobbetti
|
||||
|
||||
/// @file
|
||||
/// @brief Support for the York AC protocol (remote GRYLH2A)
|
||||
|
||||
// Note: Most of the code is autogenerated by the provided tools or assembled
|
||||
// from other support classes
|
||||
|
||||
#include "ir_York.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#ifndef ARDUINO
|
||||
#include <string>
|
||||
#endif
|
||||
#include "IRrecv.h"
|
||||
#include "IRremoteESP8266.h"
|
||||
#include "IRsend.h"
|
||||
#ifdef UNIT_TEST
|
||||
#include "IRsend_test.h"
|
||||
#endif
|
||||
#include "IRtext.h"
|
||||
#include "IRutils.h"
|
||||
|
||||
|
||||
using irutils::addBoolToString;
|
||||
using irutils::addModeToString;
|
||||
using irutils::addFanToString;
|
||||
using irutils::addTempToString;
|
||||
using irutils::addLabeledString;
|
||||
using irutils::minsToString;
|
||||
|
||||
|
||||
// Constants
|
||||
const uint16_t kYorkHdrMark = 4887;
|
||||
const uint16_t kYorkBitMark = 612;
|
||||
const uint16_t kYorkHdrSpace = 2267;
|
||||
const uint16_t kYorkOneSpace = 1778;
|
||||
const uint16_t kYorkZeroSpace = 579;
|
||||
const uint16_t kYorkFreq = 38000; // Hz. (Guessing the most common frequency.)
|
||||
|
||||
#if SEND_YORK
|
||||
/// Send a 17 Byte / 136 bit York A/C message.
|
||||
/// Status: ALPHA / Untested.
|
||||
/// @param[in] data An array of bytes containing the IR command.
|
||||
/// @param[in] nbytes Nr. of bytes of data in the array. (>=kStateLength)
|
||||
/// @param[in] repeat Nr. of times the message is to be repeated.
|
||||
void IRsend::sendYork(const uint8_t data[], const uint16_t nbytes,
|
||||
const uint16_t repeat) {
|
||||
if (nbytes < kYorkStateLength)
|
||||
return;
|
||||
sendGeneric(kYorkHdrMark, kYorkHdrSpace,
|
||||
kYorkBitMark, kYorkOneSpace,
|
||||
kYorkBitMark, kYorkZeroSpace,
|
||||
kYorkBitMark, kDefaultMessageGap,
|
||||
data, nbytes, kYorkFreq,
|
||||
false, repeat, kDutyDefault); // false == LSB
|
||||
}
|
||||
#endif // SEND_YORK
|
||||
|
||||
#if DECODE_YORK
|
||||
/// Decode the supplied message.
|
||||
/// Status: ALPHA / Tested, some values still are not mapped to the internal
|
||||
/// state of AC
|
||||
/// @param[in,out] results Ptr to the data to decode & where to store the decode
|
||||
/// @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 A boolean. True if it can decode it, false if it can't.
|
||||
bool IRrecv::decodeYork(decode_results *results, uint16_t offset,
|
||||
const uint16_t nbits, const bool strict) {
|
||||
if (strict && nbits != kYorkBits)
|
||||
return false;
|
||||
|
||||
uint16_t used = 0;
|
||||
|
||||
used = matchGeneric(results->rawbuf + offset, results->state,
|
||||
results->rawlen - offset, nbits,
|
||||
kYorkHdrMark, kYorkHdrSpace,
|
||||
kYorkBitMark, kYorkOneSpace,
|
||||
kYorkBitMark, kYorkZeroSpace,
|
||||
kYorkBitMark, kDefaultMessageGap,
|
||||
false, _tolerance, kMarkExcess,
|
||||
false); // LSB
|
||||
if (used == 0) return false; // We failed to find any data.
|
||||
|
||||
// Succes
|
||||
results->decode_type = decode_type_t::YORK;
|
||||
results->bits = nbits;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // DECODE_YORK
|
||||
|
||||
//
|
||||
//
|
||||
/// Class constructor
|
||||
/// @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?
|
||||
IRYorkAc::IRYorkAc(const uint16_t pin, const bool inverted,
|
||||
const bool use_modulation)
|
||||
: _irsend(pin, inverted, use_modulation) {
|
||||
stateReset();
|
||||
}
|
||||
|
||||
// Reset the internal state to a fixed known good state.
|
||||
void IRYorkAc::stateReset() {
|
||||
// This resets to a known-good state.
|
||||
setRaw(kYorkKnownGoodState);
|
||||
}
|
||||
|
||||
/// Set up hardware to be able to send a message.
|
||||
void IRYorkAc::begin(void) { _irsend.begin(); }
|
||||
|
||||
/// Get the raw state of the object, suitable to be sent with the appropriate
|
||||
/// IRsend object method.
|
||||
/// @return A copy of the internal state.
|
||||
uint8_t *IRYorkAc::getRaw(void) {
|
||||
calcChecksum();
|
||||
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 Length of the code in bytes.
|
||||
void IRYorkAc::setRaw(const uint8_t new_code[], const uint16_t length) {
|
||||
std::memcpy(_.raw, new_code, length);
|
||||
}
|
||||
|
||||
#if SEND_YORK
|
||||
/// Send the current internal state as an IR message.
|
||||
/// @param[in] repeat Nr. of times the message will be repeated.
|
||||
void IRYorkAc::send(const uint16_t repeat) {
|
||||
_irsend.sendYork(getRaw(), kYorkStateLength, repeat);
|
||||
}
|
||||
#endif // SEND_YORK
|
||||
|
||||
/// Get the current operation mode setting.
|
||||
/// @return The current operation mode.
|
||||
uint8_t IRYorkAc::getMode(void) const {
|
||||
return _.Mode;
|
||||
}
|
||||
|
||||
/// Set the desired operation mode.
|
||||
/// @param[in] mode The desired operation mode.
|
||||
void IRYorkAc::setMode(const uint8_t mode) {
|
||||
switch (mode) {
|
||||
case kYorkFan:
|
||||
case kYorkCool:
|
||||
case kYorkHeat:
|
||||
case kYorkDry:
|
||||
_.Mode = mode;
|
||||
break;
|
||||
default:
|
||||
_.Mode = kYorkAuto;
|
||||
}
|
||||
setFan(getFan()); // Ensure the fan is at the correct speed for the new mode.
|
||||
}
|
||||
|
||||
/// 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 IRYorkAc::convertMode(const stdAc::opmode_t mode) {
|
||||
switch (mode) {
|
||||
case stdAc::opmode_t::kCool: return kYorkCool;
|
||||
case stdAc::opmode_t::kHeat: return kYorkHeat;
|
||||
case stdAc::opmode_t::kDry: return kYorkDry;
|
||||
case stdAc::opmode_t::kFan: return kYorkFan;
|
||||
default: return kYorkAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 IRYorkAc::toCommonMode(const uint8_t mode) {
|
||||
switch (mode) {
|
||||
case kYorkCool: return stdAc::opmode_t::kCool;
|
||||
case kYorkHeat: return stdAc::opmode_t::kHeat;
|
||||
case kYorkDry: return stdAc::opmode_t::kDry;
|
||||
case kYorkFan: return stdAc::opmode_t::kFan;
|
||||
default: return stdAc::opmode_t::kAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the speed of the fan.
|
||||
/// @param[in] speed The desired setting.
|
||||
/// @note The fan speed is locked to Low when in Dry mode, to auto when in auto
|
||||
/// mode. "Fan" mode has no support for "auto" speed.
|
||||
void IRYorkAc::setFan(const uint8_t speed) {
|
||||
switch (getMode()) {
|
||||
case kYorkDry:
|
||||
_.Fan = kYorkFanLow;
|
||||
break;
|
||||
case kYorkFan:
|
||||
_.Fan = std::min(speed, kYorkFanHigh);
|
||||
break;
|
||||
case kYorkAuto:
|
||||
_.Fan = kYorkFanAuto;
|
||||
break;
|
||||
default:
|
||||
_.Fan = std::min(speed, kYorkFanAuto);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the current fan speed setting.
|
||||
/// @return The current fan speed.
|
||||
uint8_t IRYorkAc::getFan(void) const {
|
||||
return _.Fan;
|
||||
}
|
||||
|
||||
/// 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 IRYorkAc::convertFan(const stdAc::fanspeed_t speed) {
|
||||
switch (speed) {
|
||||
case stdAc::fanspeed_t::kMin:
|
||||
case stdAc::fanspeed_t::kLow:
|
||||
return kYorkFanLow;
|
||||
case stdAc::fanspeed_t::kMedium:
|
||||
return kYorkFanMedium;
|
||||
case stdAc::fanspeed_t::kHigh:
|
||||
case stdAc::fanspeed_t::kMax:
|
||||
return kYorkFanHigh;
|
||||
default:
|
||||
return kYorkFanAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 IRYorkAc::toCommonFanSpeed(const uint8_t speed) {
|
||||
switch (speed) {
|
||||
case kYorkFanHigh: return stdAc::fanspeed_t::kMax;
|
||||
case kYorkFanMedium: return stdAc::fanspeed_t::kMedium;
|
||||
case kYorkFanLow: return stdAc::fanspeed_t::kMin;
|
||||
default: return stdAc::fanspeed_t::kAuto;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the temperature.
|
||||
/// @param[in] degrees The temperature in degrees celsius.
|
||||
void IRYorkAc::setTemp(const uint8_t degrees) {
|
||||
_.Temp = std::min(kYorkMaxTemp, std::max(kYorkMinTemp, degrees));
|
||||
}
|
||||
|
||||
/// Get the current temperature setting.
|
||||
/// @return Get current setting for temp. in degrees celsius.
|
||||
uint8_t IRYorkAc::getTemp(void) const {
|
||||
return _.Temp;
|
||||
}
|
||||
|
||||
/// Set the On Timer value of the A/C.
|
||||
/// @param[in] nr_of_mins The number of minutes the timer should be.
|
||||
/// @note The timer time only has a resolution of 10 mins.
|
||||
/// @note Setting the On Timer active will cancel the Sleep timer/setting.
|
||||
void IRYorkAc::setOnTimer(const uint16_t nr_of_mins) {
|
||||
_.OnTimer = nr_of_mins / 10;
|
||||
}
|
||||
|
||||
/// Set the Off Timer value of the A/C.
|
||||
/// @param[in] nr_of_mins The number of minutes the timer should be.
|
||||
/// @note The timer time only has a resolution of 10 mins.
|
||||
/// @note Setting the Off Timer active will cancel the Sleep timer/setting.
|
||||
void IRYorkAc::setOffTimer(const uint16_t nr_of_mins) {
|
||||
_.OffTimer = nr_of_mins / 10;
|
||||
}
|
||||
|
||||
|
||||
/// Get the On Timer setting of the A/C.
|
||||
/// @return The Nr. of minutes the On Timer is set for.
|
||||
uint16_t IRYorkAc::getOnTimer(void) const {
|
||||
return _.OnTimer * 10;
|
||||
}
|
||||
|
||||
/// Get the Off Timer setting of the A/C.
|
||||
/// @return The Nr. of minutes the Off Timer is set for.
|
||||
/// @note Sleep & Off Timer share the same timer.
|
||||
uint16_t IRYorkAc::getOffTimer(void) const {
|
||||
return _.OffTimer * 10;
|
||||
}
|
||||
|
||||
/// CRC16-16 (a.k.a. CRC-16-IBM)
|
||||
void IRYorkAc::calcChecksum() {
|
||||
uint8_t length = 14;
|
||||
uint16_t reg_crc = 0x0000;
|
||||
uint8_t* data = _.raw;
|
||||
while (length--) {
|
||||
reg_crc ^= *data++;
|
||||
for (uint16_t index = 0; index < 8; index++) {
|
||||
if (reg_crc & 0x01) {
|
||||
reg_crc = (reg_crc>>1) ^ 0xA001;
|
||||
} else {
|
||||
reg_crc = reg_crc >>1;
|
||||
}
|
||||
}
|
||||
}
|
||||
_.Chk1 = (reg_crc & 0xff);
|
||||
_.Chk2 = ((reg_crc >> 8) & 0x00ff);
|
||||
}
|
||||
|
||||
/// Convert the current internal state into its stdAc::state_t equivalent.
|
||||
/// @param[in] prev Ptr to the previous state if required.
|
||||
/// @return The stdAc equivalent of the native settings.
|
||||
stdAc::state_t IRYorkAc::toCommon(const stdAc::state_t *prev) const {
|
||||
stdAc::state_t result{};
|
||||
// Start with the previous state if given it.
|
||||
if (prev != NULL) {
|
||||
result = *prev;
|
||||
} else {
|
||||
// Set defaults for non-zero values that are not implicitly set for when
|
||||
// there is no previous state.
|
||||
// e.g. Any setting that toggles should probably go here.
|
||||
result.power = false;
|
||||
}
|
||||
result.protocol = decode_type_t::YORK;
|
||||
result.mode = toCommonMode(_.Mode);
|
||||
result.celsius = true;
|
||||
result.degrees = getTemp();
|
||||
result.fanspeed = toCommonFanSpeed(_.Fan);
|
||||
result.swingv = _.SwingV ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff;
|
||||
result.sleep = getOffTimer();
|
||||
// Not supported.
|
||||
result.model = -1;
|
||||
result.turbo = false;
|
||||
result.swingh = stdAc::swingh_t::kOff;
|
||||
result.light = false;
|
||||
result.filter = false;
|
||||
result.econo = false;
|
||||
result.quiet = false;
|
||||
result.clean = false;
|
||||
result.beep = false;
|
||||
result.clock = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Convert the current internal state into a human readable string.
|
||||
/// @return A human readable string.
|
||||
String IRYorkAc::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, kYorkAuto, kYorkCool,
|
||||
kYorkHeat, kYorkDry, kYorkFan);
|
||||
result += addFanToString(_.Fan, kYorkFanHigh, kYorkFanLow,
|
||||
kYorkFanAuto, kYorkFanAuto,
|
||||
kYorkFanMedium);
|
||||
result += addTempToString(getTemp(), true);
|
||||
result += addBoolToString(_.SwingV, kSwingVStr);
|
||||
result += addLabeledString(minsToString(getOnTimer()), kOnTimerStr);
|
||||
result += addLabeledString(minsToString(getOffTimer()), kOffTimerStr);
|
||||
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
// Copyright 2022 Daniele Gobbetti
|
||||
|
||||
/// @file
|
||||
/// @brief Support for the York AC protocol (remote GRYLH2A)
|
||||
|
||||
// Supports:
|
||||
// Brand: York, Model: MHH07P17 A/C
|
||||
// Brand: York, Model: GRYLH2A remote
|
||||
|
||||
#ifndef IR_YORK_H_
|
||||
#define IR_YORK_H_
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <stdint.h>
|
||||
#ifndef UNIT_TEST
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
#include "IRremoteESP8266.h"
|
||||
#include "IRsend.h"
|
||||
#ifdef UNIT_TEST
|
||||
#include "IRsend_test.h"
|
||||
#endif
|
||||
|
||||
|
||||
/// Native representation of a York A/C message.
|
||||
union YorkProtocol{
|
||||
uint8_t raw[kYorkStateLength]; ///< The state of the IR remote.
|
||||
struct {
|
||||
// byte 0-5
|
||||
uint8_t preamble[6]; // unknown, fixed 0x08, 0x10, 0x07, 0x02, 0x40, 0x08
|
||||
// byte 6
|
||||
uint8_t Key1 :4; // key pressed on the remote: 1 power, 2 temp up, 3
|
||||
// temp down...
|
||||
uint8_t Key2 :4; // only set when setting ontime/offtime:
|
||||
// Key1 value is 0x6 (enter key) and Key2 is 0x3 for
|
||||
// "start" and 0x2 for "stop"
|
||||
// byte 7
|
||||
uint8_t Fan :4; // Fan speed: 1 low, 2 mid, 3 max, 8 auto
|
||||
uint8_t Power :1; // main unit power: 1 on, 0 off
|
||||
uint8_t :3;
|
||||
// byte 8
|
||||
uint8_t Mode :4; // 1 heat, 2 cool, 3 dry, 4 fan, 8 auto
|
||||
uint8_t :4;
|
||||
// byte 9
|
||||
uint8_t :2;
|
||||
uint8_t Temp :6; // Degrees Celsius
|
||||
// byte 10
|
||||
uint8_t OffTimer :8; // Power off time: 10s of minutes from now
|
||||
// byte 11
|
||||
uint8_t OnTimer :8; // Power on time: 10s of minutes from now
|
||||
// byte 12
|
||||
uint8_t :8; // unknown, normally 0x00, could be 0x08 when ontime
|
||||
// set, 0x88 if both on and offtime set, 0x60 if
|
||||
// sleep mode set
|
||||
// byte 13
|
||||
uint8_t SwingV :1; // 0 off, 1 on
|
||||
uint8_t :7;
|
||||
// byte 14
|
||||
uint8_t :8; // checksum preamble, fixed 0xEC
|
||||
// byte 15-16
|
||||
uint8_t Chk1 :8; // checksum, algorithm CRC-16/ARC, first byte
|
||||
uint8_t Chk2 :8; // checksum, algorithm CRC-16/ARC, second byte
|
||||
};
|
||||
};
|
||||
|
||||
// Constants
|
||||
const uint8_t kYorkKnownGoodState[kYorkStateLength] = {
|
||||
0x08, 0x10, 0x07, 0x02, 0x40, 0x08,
|
||||
0x03, 0x18, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||
0xEC,
|
||||
0xF5, 0xF2}; // Mode "Heat", Fan Speed "auto", Temp: 24, Power: on
|
||||
|
||||
// Temperature
|
||||
const uint8_t kYorkMinTemp = 18; // Celsius
|
||||
const uint8_t kYorkMaxTemp = 32; // Celsius
|
||||
// Fan
|
||||
const uint8_t kYorkFanLow = 1;
|
||||
const uint8_t kYorkFanMedium = 2;
|
||||
const uint8_t kYorkFanHigh = 3;
|
||||
const uint8_t kYorkFanAuto = 8;
|
||||
// Modes
|
||||
const uint8_t kYorkHeat = 1;
|
||||
const uint8_t kYorkCool = 2;
|
||||
const uint8_t kYorkDry = 3;
|
||||
const uint8_t kYorkFan = 4;
|
||||
const uint8_t kYorkAuto = 8;
|
||||
|
||||
// Classes
|
||||
/// Class for handling detailed York A/C messages.
|
||||
class IRYorkAc {
|
||||
public:
|
||||
explicit IRYorkAc(const uint16_t pin, const bool inverted = false,
|
||||
const bool use_modulation = true);
|
||||
void stateReset();
|
||||
#if SEND_YORK
|
||||
void send(const uint16_t repeat = kNoRepeat);
|
||||
/// Run the calibration to calculate uSec timing offsets for this platform.
|
||||
/// @return The uSec timing offset needed per modulation of the IR Led.
|
||||
/// @note This will produce a 65ms IR signal pulse at 38kHz.
|
||||
/// Only ever needs to be run once per object instantiation, if at all.
|
||||
int8_t calibrate(void) { return _irsend.calibrate(); }
|
||||
#endif // SEND_YORK
|
||||
void begin();
|
||||
void setPowerToggle(const bool on);
|
||||
bool getPowerToggle() const;
|
||||
void setTemp(const uint8_t temp);
|
||||
uint8_t getTemp() const;
|
||||
void setFan(const uint8_t speed);
|
||||
uint8_t getFan() const;
|
||||
void setMode(const uint8_t mode);
|
||||
uint8_t getMode() const;
|
||||
uint16_t getOnTimer(void) const;
|
||||
uint16_t getOffTimer(void) const;
|
||||
void setOnTimer(const uint16_t mins);
|
||||
void setOffTimer(const uint16_t mins);
|
||||
uint8_t* getRaw();
|
||||
void setRaw(const uint8_t new_code[],
|
||||
const uint16_t length = kYorkStateLength);
|
||||
static uint8_t convertMode(const stdAc::opmode_t mode);
|
||||
static uint8_t convertFan(const stdAc::fanspeed_t speed);
|
||||
void calcChecksum();
|
||||
static stdAc::opmode_t toCommonMode(const uint8_t mode);
|
||||
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
|
||||
stdAc::state_t toCommon(const stdAc::state_t *prev = NULL) const;
|
||||
String toString() const;
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
private:
|
||||
IRsend _irsend; ///< Instance of the IR send class
|
||||
#else
|
||||
/// @cond IGNORE
|
||||
IRsendTest _irsend; ///< Instance of the testing IR send class
|
||||
/// @endcond
|
||||
#endif
|
||||
YorkProtocol _;
|
||||
};
|
||||
#endif // IR_YORK_H_
|
|
@ -310,6 +310,9 @@ D_STR_INDIRECT " " D_STR_MODE
|
|||
#ifndef D_STR_LOCK
|
||||
#define D_STR_LOCK "Lock"
|
||||
#endif // D_STR_LOCK
|
||||
#ifndef D_STR_REPORT
|
||||
#define D_STR_REPORT "Report"
|
||||
#endif // D_STR_REPORT
|
||||
|
||||
#ifndef D_STR_AUTO
|
||||
#define D_STR_AUTO "Auto"
|
||||
|
@ -378,6 +381,9 @@ D_STR_INDIRECT " " D_STR_MODE
|
|||
#ifndef D_STR_MEDIUM
|
||||
#define D_STR_MEDIUM "Medium"
|
||||
#endif // D_STR_MEDIUM
|
||||
#ifndef D_STR_MED_HIGH
|
||||
#define D_STR_MED_HIGH D_STR_MED "-" D_STR_HIGH
|
||||
#endif // D_STR_MED_HIGH
|
||||
|
||||
#ifndef D_STR_HIGHEST
|
||||
#define D_STR_HIGHEST "Highest"
|
||||
|
@ -445,6 +451,33 @@ D_STR_INDIRECT " " D_STR_MODE
|
|||
#ifndef D_STR_BOTTOM
|
||||
#define D_STR_BOTTOM "Bottom"
|
||||
#endif // D_STR_BOTTOM
|
||||
#ifndef D_STR_UPPER_MIDDLE
|
||||
#define D_STR_UPPER_MIDDLE D_STR_UPPER "-" D_STR_MIDDLE
|
||||
#endif // D_STR_UPPER_MIDDLE
|
||||
#ifndef D_STR_CONFIG
|
||||
#define D_STR_CONFIG "Config"
|
||||
#endif // D_STR_CONFIG
|
||||
#ifndef D_STR_CONTROL
|
||||
#define D_STR_CONTROL "Control"
|
||||
#endif // D_STR_CONTROL
|
||||
#ifndef D_STR_SET_TIMER
|
||||
#define D_STR_SET_TIMER D_STR_SET " " D_STR_TIMER
|
||||
#endif // D_STR_AC_TIMER
|
||||
#ifndef D_STR_SCHEDULE
|
||||
#define D_STR_SCHEDULE "Schedule"
|
||||
#endif // D_STR_SCHEDULE
|
||||
#ifndef D_STR_CH
|
||||
#define D_STR_CH "CH#"
|
||||
#endif // D_STR_CH
|
||||
#ifndef D_STR_TIMER_ACTIVE_DAYS
|
||||
#define D_STR_TIMER_ACTIVE_DAYS "TimerActiveDays"
|
||||
#endif // D_STR_TIMER_ACTIVE_DAYS
|
||||
#ifndef D_STR_KEY
|
||||
#define D_STR_KEY "Key"
|
||||
#endif // D_STR_KEY
|
||||
#ifndef D_STR_VALUE
|
||||
#define D_STR_VALUE "Value"
|
||||
#endif // D_STR_VALUE
|
||||
|
||||
// Compound words/phrases/descriptions from pre-defined words.
|
||||
// Note: Obviously these need to be defined *after* their component words.
|
||||
|
@ -472,6 +505,9 @@ D_STR_INDIRECT " " D_STR_MODE
|
|||
#ifndef D_STR_DISPLAYTEMP
|
||||
#define D_STR_DISPLAYTEMP D_STR_DISPLAY " " D_STR_TEMP
|
||||
#endif // D_STR_DISPLAYTEMP
|
||||
#ifndef D_STR_IFEELREPORT
|
||||
#define D_STR_IFEELREPORT D_STR_IFEEL " " D_STR_REPORT
|
||||
#endif // D_STR_IFEELREPORT
|
||||
#ifndef D_STR_SENSORTEMP
|
||||
#define D_STR_SENSORTEMP D_STR_SENSOR " " D_STR_TEMP
|
||||
#endif // D_STR_SENSORTEMP
|
||||
|
@ -689,6 +725,12 @@ D_STR_INDIRECT " " D_STR_MODE
|
|||
#ifndef D_STR_DG11J191
|
||||
#define D_STR_DG11J191 "DG11J191"
|
||||
#endif // D_STR_DG11J191
|
||||
#ifndef D_STR_ARGO_WREM2
|
||||
#define D_STR_ARGO_WREM2 "WREM2"
|
||||
#endif // D_STR_ARGO_WREM2
|
||||
#ifndef D_STR_ARGO_WREM3
|
||||
#define D_STR_ARGO_WREM3 "WREM3"
|
||||
#endif // D_STR_ARGO_WREM3
|
||||
|
||||
// Protocols Names
|
||||
#ifndef D_STR_AIRTON
|
||||
|
@ -727,6 +769,9 @@ D_STR_INDIRECT " " D_STR_MODE
|
|||
#ifndef D_STR_CARRIER_AC64
|
||||
#define D_STR_CARRIER_AC64 D_STR_CARRIER_AC "64"
|
||||
#endif // D_STR_CARRIER_AC64
|
||||
#ifndef D_STR_CARRIER_AC84
|
||||
#define D_STR_CARRIER_AC84 D_STR_CARRIER_AC "84"
|
||||
#endif // D_STR_CARRIER_AC84
|
||||
#ifndef D_STR_CARRIER_AC128
|
||||
#define D_STR_CARRIER_AC128 D_STR_CARRIER_AC "128"
|
||||
#endif // D_STR_CARRIER_AC128
|
||||
|
@ -808,6 +853,9 @@ D_STR_INDIRECT " " D_STR_MODE
|
|||
#ifndef D_STR_GOODWEATHER
|
||||
#define D_STR_GOODWEATHER "GOODWEATHER"
|
||||
#endif // D_STR_GOODWEATHER
|
||||
#ifndef D_STR_GORENJE
|
||||
#define D_STR_GORENJE "GORENJE"
|
||||
#endif // D_STR_GORENJE
|
||||
#ifndef D_STR_GREE
|
||||
#define D_STR_GREE "GREE"
|
||||
#endif // D_STR_GREE
|
||||
|
@ -1060,9 +1108,15 @@ D_STR_INDIRECT " " D_STR_MODE
|
|||
#ifndef D_STR_WHYNTER
|
||||
#define D_STR_WHYNTER "WHYNTER"
|
||||
#endif // D_STR_WHYNTER
|
||||
#ifndef D_STR_WOWWEE
|
||||
#define D_STR_WOWWEE "WOWWEE"
|
||||
#endif // D_STR_WOWWEE
|
||||
#ifndef D_STR_XMP
|
||||
#define D_STR_XMP "XMP"
|
||||
#endif // D_STR_XMP
|
||||
#ifndef D_STR_YORK
|
||||
#define D_STR_YORK "YORK"
|
||||
#endif // D_STR_YORK
|
||||
#ifndef D_STR_ZEPEAL
|
||||
#define D_STR_ZEPEAL "ZEPEAL"
|
||||
#endif // D_STR_ZEPEAL
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
// Copyright 2022 - Stijn (@stijnb1234)
|
||||
// Locale/language file for Dutch / The Netherlands.
|
||||
// This file will override the default values located in `defaults.h`.
|
||||
#ifndef LOCALE_NL_NL_H_
|
||||
#define LOCALE_NL_NL_H_
|
||||
|
||||
#define D_STR_UNKNOWN "ONBEKEND"
|
||||
#define D_STR_POWER "Stroom"
|
||||
#define D_STR_PREVIOUS "Vorige"
|
||||
#define D_STR_ON "Aan"
|
||||
#define D_STR_OFF "Uit"
|
||||
#define D_STR_MODE "Modus"
|
||||
#define D_STR_TOGGLE "Omschakelen"
|
||||
#define D_STR_SLEEP "Slaap"
|
||||
#define D_STR_LIGHT "Licht"
|
||||
#define D_STR_POWERFUL "Sterk"
|
||||
#define D_STR_QUIET "Rustig"
|
||||
#define D_STR_ECONO "Eco"
|
||||
#define D_STR_SWING "Zwaai"
|
||||
#define D_STR_BEEP "Piep"
|
||||
#define D_STR_MOULD "Schimmel"
|
||||
#define D_STR_CLEAN "Reinigen"
|
||||
#define D_STR_PURIFY "Zuiver"
|
||||
#define D_STR_TIMER "Timer"
|
||||
#define D_STR_ONTIMER D_STR_TIMER " " D_STR_ON
|
||||
#define D_STR_OFFTIMER D_STR_TIMER " " D_STR_OFF
|
||||
#define D_STR_CLOCK "Klok"
|
||||
#define D_STR_COMMAND "Commando"
|
||||
#define D_STR_XFAN "XVentilator"
|
||||
#define D_STR_HEALTH "Gezondheid"
|
||||
#define D_STR_IFEEL "IkVoel"
|
||||
#define D_STR_ISEE "IkZie"
|
||||
#define D_STR_HUMID "Vochtigheid"
|
||||
#define D_STR_SAVE "Opslaan"
|
||||
#define D_STR_EYE "Ogen"
|
||||
#define D_STR_FOLLOW "Volgen"
|
||||
#define D_STR_FRESH "Fris"
|
||||
#define D_STR_HOLD "Houd"
|
||||
#define D_STR_BUTTON "Knop"
|
||||
#define D_STR_NIGHT "Nacht"
|
||||
#define D_STR_SILENT "Stil"
|
||||
#define D_STR_UP "Omhoog"
|
||||
#define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
|
||||
#define D_STR_DOWN "Omlaag"
|
||||
#define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
|
||||
#define D_STR_CHANGE "Wisselen"
|
||||
#define D_STR_MOVE "Verplaatsen"
|
||||
#define D_STR_SET "Instellen"
|
||||
#define D_STR_CANCEL "Annuleren"
|
||||
#define D_STR_COMFORT "Comfortabel"
|
||||
#define D_STR_WEEKLY "Weekelijks"
|
||||
#define D_STR_WEEKLYTIMER D_STR_TIMER " " D_STR_WEEKLY
|
||||
#define D_STR_FAST "Snel"
|
||||
#define D_STR_SLOW "Langzaam"
|
||||
#define D_STR_AIRFLOW "Luchtstroom"
|
||||
#define D_STR_STEP "Stap"
|
||||
#define D_STR_NA "N/A"
|
||||
#define D_STR_OUTSIDE "Buiten"
|
||||
#define D_STR_LOUD "Luid"
|
||||
#define D_STR_UPPER "Boven"
|
||||
#define D_STR_LOWER "Beneden"
|
||||
#define D_STR_BREEZE "Wind"
|
||||
#define D_STR_CIRCULATE "Circulatie"
|
||||
#define D_STR_CEILING "Plafond"
|
||||
#define D_STR_WALL "Muur"
|
||||
#define D_STR_ROOM "Kamer"
|
||||
#define D_STR_6THSENSE "6e Zintuig"
|
||||
#define D_STR_FIXED "Vast"
|
||||
|
||||
#define D_STR_AUTOMATIC "Automatisch"
|
||||
#define D_STR_MANUAL "Handmatig"
|
||||
#define D_STR_COOL "Koelen"
|
||||
#define D_STR_HEAT "Verwarmen"
|
||||
#define D_STR_FAN "Venilator"
|
||||
#define D_STR_FANONLY "alleen_fan"
|
||||
#define D_STR_DRY "Drogen"
|
||||
|
||||
#define D_STR_MED "Mid"
|
||||
#define D_STR_MEDIUM "Medium"
|
||||
|
||||
#define D_STR_HIGHEST "Hoogste"
|
||||
#define D_STR_HIGH "Hoog"
|
||||
#define D_STR_HI "H"
|
||||
#define D_STR_MID "M"
|
||||
#define D_STR_MIDDLE "Medium"
|
||||
#define D_STR_LOW "Laag"
|
||||
#define D_STR_LO "L"
|
||||
#define D_STR_LOWEST "Laagste"
|
||||
#define D_STR_RIGHT "Rechts"
|
||||
#define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT
|
||||
#define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX
|
||||
#define D_STR_LEFT "Links"
|
||||
#define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT
|
||||
#define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX
|
||||
#define D_STR_WIDE "Breed"
|
||||
#define D_STR_CENTRE "Midden"
|
||||
#define D_STR_TOP "Boven"
|
||||
#define D_STR_BOTTOM "Onder"
|
||||
|
||||
#define D_STR_DAY "Dag"
|
||||
#define D_STR_DAYS D_STR_DAY "en"
|
||||
#define D_STR_HOUR "Uur"
|
||||
#define D_STR_HOURS D_STR_HOUR
|
||||
#define D_STR_MINUTE "Minuut"
|
||||
#define D_STR_MINUTES "Minuten"
|
||||
#define D_STR_SECOND "Seconde"
|
||||
#define D_STR_SECONDS D_STR_SECOND "n"
|
||||
#define D_STR_NOW "Nu"
|
||||
#define D_STR_THREELETTERDAYS "ZonMaaDinWoeDonVriZat"
|
||||
|
||||
#define D_STR_YES "Ja"
|
||||
#define D_STR_NO "Nee"
|
||||
#define D_STR_TRUE "Waar"
|
||||
#define D_STR_FALSE "Niet Waar"
|
||||
|
||||
#define D_STR_REPEAT "Herhalen"
|
||||
#define D_STR_PREVIOUS "Vorige"
|
||||
#define D_STR_DISPLAY "Display"
|
||||
#define D_STR_INSIDE "Binnen"
|
||||
#define D_STR_POWERBUTTON "Hoofdschakelaar"
|
||||
#define D_STR_PREVIOUSPOWER "Vorige inschakelstatus"
|
||||
#define D_STR_DISPLAYTEMP "Temperatuurweergave"
|
||||
|
||||
// IRrecvDumpV2+
|
||||
#define D_STR_TIMESTAMP "Tijdsaanduiding"
|
||||
#define D_STR_LIBRARY "Bibliotheek"
|
||||
#define D_STR_TOLERANCE "Tolerantie"
|
||||
#define D_STR_MESGDESC "Beschrijving"
|
||||
#define D_STR_IRRECVDUMP_STARTUP \
|
||||
"IRrecvDump draait en wacht op IR-signaal op pin %d"
|
||||
#define D_WARN_BUFFERFULL \
|
||||
"WAARSCHUWING: IR-code is te groot voor buffer (>= %d). " \
|
||||
"Het resultaat kan niet worden vertrouwd totdat het is verholpen. " \
|
||||
"Wijzig & vergroot `kCaptureBufferSize`."
|
||||
|
||||
#endif // LOCALE_NL_NL_H_
|
|
@ -73,6 +73,7 @@ TEST(TestIRac, Airton) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Airwell) {
|
||||
|
@ -96,6 +97,7 @@ TEST(TestIRac, Airwell) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Amcor) {
|
||||
|
@ -119,6 +121,7 @@ TEST(TestIRac, Amcor) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Argo) {
|
||||
|
@ -130,16 +133,19 @@ TEST(TestIRac, Argo) {
|
|||
true, // Power
|
||||
stdAc::opmode_t::kHeat, // Mode
|
||||
21, // Celsius
|
||||
22, // Sensor Temp.
|
||||
stdAc::fanspeed_t::kHigh, // Fan speed
|
||||
stdAc::swingv_t::kOff, // Vertical swing
|
||||
false, // iFeel
|
||||
false, // Turbo
|
||||
-1); // Sleep
|
||||
EXPECT_TRUE(ac.getPower());
|
||||
EXPECT_EQ(kArgoHeat, ac.getMode());
|
||||
EXPECT_EQ(21, ac.getTemp());
|
||||
EXPECT_EQ(kArgoFlapAuto, ac.getFlap());
|
||||
EXPECT_EQ(kArgoFlapFull, ac.getFlap());
|
||||
EXPECT_FALSE(ac.getMax()); // Turbo
|
||||
EXPECT_FALSE(ac.getNight()); // Sleep
|
||||
EXPECT_EQ(argoIrMessageType_t::AC_CONTROL, ac.getMessageType());
|
||||
}
|
||||
|
||||
TEST(TestIRac, Carrier64) {
|
||||
|
@ -174,6 +180,7 @@ TEST(TestIRac, Carrier64) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Coolix) {
|
||||
|
@ -189,9 +196,11 @@ TEST(TestIRac, Coolix) {
|
|||
true, // Power
|
||||
stdAc::opmode_t::kHeat, // Mode
|
||||
21, // Celsius
|
||||
kNoTempValue, // Sensor Temp
|
||||
stdAc::fanspeed_t::kHigh, // Fan speed
|
||||
stdAc::swingv_t::kOff, // Vertical swing
|
||||
stdAc::swingh_t::kOff, // Horizontal swing
|
||||
false, // iFeel
|
||||
false, // Turbo
|
||||
false, // Light
|
||||
false, // Clean
|
||||
|
@ -235,6 +244,7 @@ TEST(TestIRac, Coolix) {
|
|||
// End of message #2 (i.e. Repeat '1')
|
||||
// Note: the two messages (#1 & #2) are identical.
|
||||
ac._irsend.outputStr());
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Corona) {
|
||||
|
@ -277,6 +287,7 @@ TEST(TestIRac, Corona) {
|
|||
ASSERT_EQ(expectedCapture, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin) {
|
||||
|
@ -310,6 +321,7 @@ TEST(TestIRac, Daikin) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin128) {
|
||||
|
@ -343,6 +355,7 @@ TEST(TestIRac, Daikin128) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin152) {
|
||||
|
@ -371,6 +384,7 @@ TEST(TestIRac, Daikin152) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin160) {
|
||||
|
@ -396,6 +410,7 @@ TEST(TestIRac, Daikin160) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin176) {
|
||||
|
@ -421,6 +436,7 @@ TEST(TestIRac, Daikin176) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin2) {
|
||||
|
@ -460,6 +476,7 @@ TEST(TestIRac, Daikin2) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin216) {
|
||||
|
@ -488,6 +505,7 @@ TEST(TestIRac, Daikin216) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Daikin64) {
|
||||
|
@ -548,7 +566,7 @@ TEST(TestIRac, Ecoclim) {
|
|||
IRac irac(kGpioUnused);
|
||||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Power: On, Mode: 1 (Cool), Temp: 26C, SensorTemp: 26C, Fan: 2 (High), "
|
||||
"Power: On, Mode: 1 (Cool), Temp: 26C, SensorTemp: 27C, Fan: 2 (High), "
|
||||
"Clock: 12:34, On Timer: Off, Off Timer: Off, Type: 0";
|
||||
|
||||
ac.begin();
|
||||
|
@ -556,6 +574,7 @@ TEST(TestIRac, Ecoclim) {
|
|||
true, // Power
|
||||
stdAc::opmode_t::kCool, // Mode
|
||||
26, // Celsius
|
||||
27, // Sensor Temp.
|
||||
stdAc::fanspeed_t::kHigh, // Fan speed
|
||||
-1, // Sleep
|
||||
12 * 60 + 34); // Clock
|
||||
|
@ -567,7 +586,7 @@ TEST(TestIRac, Ecoclim) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
|
||||
char expected_sleep[] =
|
||||
"Power: On, Mode: 7 (Sleep), Temp: 21C, SensorTemp: 21C, Fan: 0 (Low), "
|
||||
"Power: On, Mode: 7 (Sleep), Temp: 21C, SensorTemp: 22C, Fan: 0 (Low), "
|
||||
"Clock: 17:17, On Timer: Off, Off Timer: Off, Type: 0";
|
||||
|
||||
ac._irsend.reset();
|
||||
|
@ -575,6 +594,7 @@ TEST(TestIRac, Ecoclim) {
|
|||
true, // Power
|
||||
stdAc::opmode_t::kCool, // Mode
|
||||
21, // Celsius
|
||||
22, // Sensor Temp.
|
||||
stdAc::fanspeed_t::kLow, // Fan speed
|
||||
8 * 60, // Sleep
|
||||
17 * 60 + 17); // Clock
|
||||
|
@ -600,9 +620,11 @@ TEST(TestIRac, Electra) {
|
|||
true, // Power
|
||||
stdAc::opmode_t::kFan, // Mode
|
||||
26, // Celsius
|
||||
27, // Sensor Temp.
|
||||
stdAc::fanspeed_t::kHigh, // Fan speed
|
||||
stdAc::swingv_t::kAuto, // Vertical swing
|
||||
stdAc::swingh_t::kLeft, // Horizontal swing
|
||||
false, // iFeel
|
||||
true, // Turbo
|
||||
true, // Light (toggle)
|
||||
true); // Clean
|
||||
|
@ -656,6 +678,7 @@ TEST(TestIRac, Fujitsu) {
|
|||
ASSERT_EQ(ardb1_expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
ac._irsend.reset();
|
||||
// Try to set the device to 10C Heat mode.
|
||||
|
@ -681,6 +704,7 @@ TEST(TestIRac, Fujitsu) {
|
|||
ASSERT_EQ(kFujitsuAcBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(arrah2e_expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
ac._irsend.reset();
|
||||
irac.fujitsu(&ac,
|
||||
fujitsu_ac_remote_model_t::ARRY4, // Model
|
||||
|
@ -703,6 +727,7 @@ TEST(TestIRac, Fujitsu) {
|
|||
ASSERT_EQ(kFujitsuAcBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(arry4_expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
ac._irsend.reset();
|
||||
irac.fujitsu(&ac,
|
||||
|
@ -753,6 +778,7 @@ TEST(TestIRac, Goodweather) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Gree) {
|
||||
|
@ -761,7 +787,7 @@ TEST(TestIRac, Gree) {
|
|||
IRrecv capture(kGpioUnused);
|
||||
char expected[] =
|
||||
"Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 71F, "
|
||||
"Fan: 2 (Medium), Turbo: Off, Econo: Off, IFeel: Off, WiFi: Off, "
|
||||
"Fan: 2 (Medium), Turbo: Off, Econo: Off, IFeel: On, WiFi: Off, "
|
||||
"XFan: On, Light: On, Sleep: On, Swing(V) Mode: Manual, "
|
||||
"Swing(V): 3 (UNKNOWN), Swing(H): 5 (Right), Timer: Off, "
|
||||
"Display Temp: 0 (Off)";
|
||||
|
@ -776,6 +802,7 @@ TEST(TestIRac, Gree) {
|
|||
stdAc::fanspeed_t::kMedium, // Fan speed
|
||||
stdAc::swingv_t::kHigh, // Vertical swing
|
||||
stdAc::swingh_t::kRight, // Horizontal swing
|
||||
true, // iFeel
|
||||
false, // Turbo
|
||||
false, // Econo
|
||||
true, // Light
|
||||
|
@ -789,6 +816,7 @@ TEST(TestIRac, Gree) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Haier) {
|
||||
|
@ -818,6 +846,7 @@ TEST(TestIRac, Haier) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Haier160) {
|
||||
|
@ -853,6 +882,7 @@ TEST(TestIRac, Haier160) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Haier176) {
|
||||
|
@ -886,6 +916,7 @@ TEST(TestIRac, Haier176) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, HaierYrwo2) {
|
||||
|
@ -919,6 +950,7 @@ TEST(TestIRac, HaierYrwo2) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Hitachi) {
|
||||
|
@ -946,6 +978,7 @@ TEST(TestIRac, Hitachi) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Hitachi1) {
|
||||
|
@ -978,6 +1011,7 @@ TEST(TestIRac, Hitachi1) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Hitachi264) {
|
||||
|
@ -1003,6 +1037,7 @@ TEST(TestIRac, Hitachi264) {
|
|||
ASSERT_EQ(expected_swingon, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
EXPECT_EQ(decode_type_t::HITACHI_AC264, r.protocol);
|
||||
EXPECT_TRUE(r.power);
|
||||
EXPECT_EQ(stdAc::opmode_t::kHeat, r.mode);
|
||||
|
@ -1031,6 +1066,7 @@ TEST(TestIRac, Hitachi296) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
EXPECT_EQ(decode_type_t::HITACHI_AC296, r.protocol);
|
||||
EXPECT_TRUE(r.power);
|
||||
EXPECT_EQ(stdAc::opmode_t::kHeat, r.mode);
|
||||
|
@ -1062,6 +1098,7 @@ TEST(TestIRac, Hitachi344) {
|
|||
ASSERT_EQ(expected_swingon, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
EXPECT_EQ(decode_type_t::HITACHI_AC344, r.protocol);
|
||||
EXPECT_TRUE(r.power);
|
||||
EXPECT_EQ(stdAc::opmode_t::kHeat, r.mode);
|
||||
|
@ -1082,6 +1119,7 @@ TEST(TestIRac, Hitachi344) {
|
|||
ASSERT_EQ(expected_swingoff, ac.toString());
|
||||
ac._irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
ASSERT_EQ(HITACHI_AC344, ac._irsend.capture.decode_type);
|
||||
ASSERT_EQ(kHitachiAc344Bits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(expected_swingoff,
|
||||
|
@ -1115,6 +1153,7 @@ TEST(TestIRac, Hitachi424) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
ac._irsend.reset();
|
||||
irac.hitachi424(&ac,
|
||||
|
@ -1131,6 +1170,7 @@ TEST(TestIRac, Hitachi424) {
|
|||
ASSERT_EQ(kHitachiAc424Bits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(expected_swingv, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Kelvinator) {
|
||||
|
@ -1164,6 +1204,7 @@ TEST(TestIRac, Kelvinator) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, LG) {
|
||||
|
@ -1196,6 +1237,7 @@ TEST(TestIRac, LG) {
|
|||
ASSERT_EQ(61, ac._irsend.capture.rawlen);
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, LG2) {
|
||||
|
@ -1228,6 +1270,7 @@ TEST(TestIRac, LG2) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
// Message #2 - SwingV Low
|
||||
EXPECT_TRUE(capture.decodeLG(&ac._irsend.capture, 61));
|
||||
ASSERT_EQ(LG2, ac._irsend.capture.decode_type);
|
||||
|
@ -1443,6 +1486,7 @@ TEST(TestIRac, LG2_AKB73757604) {
|
|||
ASSERT_EQ(LG2, ac._irsend.capture.decode_type);
|
||||
ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(kLgAcSwingHAuto, ac._irsend.capture.value);
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Midea) {
|
||||
|
@ -1461,8 +1505,10 @@ TEST(TestIRac, Midea) {
|
|||
stdAc::opmode_t::kDry, // Mode
|
||||
true, // Celsius
|
||||
27, // Degrees
|
||||
28, // Sensor Temp.
|
||||
stdAc::fanspeed_t::kMedium, // Fan speed
|
||||
stdAc::swingv_t::kOff, // Swing(V)
|
||||
false, // iFeel
|
||||
false, // Silent/Quiet
|
||||
false, // Previous Silent/Quiet setting
|
||||
false, // Turbo
|
||||
|
@ -1479,6 +1525,7 @@ TEST(TestIRac, Midea) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Mirage) {
|
||||
|
@ -1518,6 +1565,7 @@ TEST(TestIRac, Mirage) {
|
|||
ASSERT_EQ(kMirageBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(expected_KKG9AC1, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
const char expected_KKG29AC1[] =
|
||||
"Model: 2 (KKG29AC1), Power: On, Mode: 3 (Dry), Temp: 27C, "
|
||||
|
@ -1535,6 +1583,7 @@ TEST(TestIRac, Mirage) {
|
|||
ASSERT_EQ(expected_KKG29AC1,
|
||||
IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Mitsubishi) {
|
||||
|
@ -1567,6 +1616,7 @@ TEST(TestIRac, Mitsubishi) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Mitsubishi136) {
|
||||
|
@ -1593,6 +1643,7 @@ TEST(TestIRac, Mitsubishi136) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, MitsubishiHeavy88) {
|
||||
|
@ -1623,6 +1674,7 @@ TEST(TestIRac, MitsubishiHeavy88) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, MitsubishiHeavy152) {
|
||||
|
@ -1656,6 +1708,7 @@ TEST(TestIRac, MitsubishiHeavy152) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Neoclima) {
|
||||
|
@ -1690,6 +1743,7 @@ TEST(TestIRac, Neoclima) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Panasonic) {
|
||||
|
@ -1722,6 +1776,7 @@ TEST(TestIRac, Panasonic) {
|
|||
ASSERT_EQ(expected_nke, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
char expected_dke[] =
|
||||
"Model: 3 (DKE), Power: On, Mode: 3 (Cool), Temp: 18C, Fan: 4 (Maximum), "
|
||||
|
@ -1748,6 +1803,7 @@ TEST(TestIRac, Panasonic) {
|
|||
ASSERT_EQ(kPanasonicAcBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(expected_dke, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Panasonic32) {
|
||||
|
@ -1774,6 +1830,7 @@ TEST(TestIRac, Panasonic32) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Samsung) {
|
||||
|
@ -1813,6 +1870,7 @@ TEST(TestIRac, Samsung) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
ac._irsend.reset();
|
||||
irac.samsung(&ac,
|
||||
|
@ -1841,6 +1899,7 @@ TEST(TestIRac, Samsung) {
|
|||
ASSERT_EQ(kSamsungAcExtendedBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
ac._irsend.reset();
|
||||
const char sleep[] =
|
||||
|
@ -1874,6 +1933,7 @@ TEST(TestIRac, Samsung) {
|
|||
ASSERT_EQ(kSamsungAcExtendedBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(sleep, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Sanyo) {
|
||||
|
@ -1890,8 +1950,10 @@ TEST(TestIRac, Sanyo) {
|
|||
true, // Power
|
||||
stdAc::opmode_t::kCool, // Mode
|
||||
28, // Celsius
|
||||
kNoTempValue, // SensorTemp
|
||||
stdAc::fanspeed_t::kMedium, // Fan speed
|
||||
stdAc::swingv_t::kHighest, // Vertical Swing
|
||||
false, // iFeel
|
||||
true, // Beep
|
||||
17); // Sleep
|
||||
ASSERT_EQ(expected, ac.toString());
|
||||
|
@ -1902,6 +1964,7 @@ TEST(TestIRac, Sanyo) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Sanyo88) {
|
||||
|
@ -1931,6 +1994,7 @@ TEST(TestIRac, Sanyo88) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Sharp) {
|
||||
|
@ -1963,6 +2027,7 @@ TEST(TestIRac, Sharp) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Tcl112) {
|
||||
|
@ -1997,6 +2062,7 @@ TEST(TestIRac, Tcl112) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
// Test the quiet mode, which should generate two messages.
|
||||
ac._irsend.reset();
|
||||
irac.tcl112(&ac,
|
||||
|
@ -2052,6 +2118,7 @@ TEST(TestIRac, Technibel) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Teco) {
|
||||
|
@ -2079,6 +2146,7 @@ TEST(TestIRac, Teco) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Toshiba) {
|
||||
|
@ -2108,6 +2176,7 @@ TEST(TestIRac, Toshiba) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4400s4300"
|
||||
|
@ -2183,6 +2252,7 @@ TEST(TestIRac, Transcold) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Trotec) {
|
||||
|
@ -2212,6 +2282,7 @@ TEST(TestIRac, Trotec) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Trotec3550) {
|
||||
|
@ -2242,6 +2313,7 @@ TEST(TestIRac, Trotec3550) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Truma) {
|
||||
|
@ -2271,6 +2343,7 @@ TEST(TestIRac, Truma) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, Vestel) {
|
||||
|
@ -2300,6 +2373,7 @@ TEST(TestIRac, Vestel) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
ac._irsend.reset();
|
||||
char expected_clocks[] =
|
||||
|
@ -2325,6 +2399,7 @@ TEST(TestIRac, Vestel) {
|
|||
ASSERT_EQ(kVestelAcBits, ac._irsend.capture.bits);
|
||||
ASSERT_EQ(expected_clocks, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
// Now check it sends both messages during normal operation when the
|
||||
// clock is set.
|
||||
|
@ -2404,6 +2479,7 @@ TEST(TestIRac, Voltas) {
|
|||
ASSERT_EQ(expected_unknown, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
ac._irsend.reset();
|
||||
// Test the UNKNOWN model type
|
||||
|
@ -2470,6 +2546,7 @@ TEST(TestIRac, Whirlpool) {
|
|||
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
TEST(TestIRac, cmpStates) {
|
||||
|
@ -2507,6 +2584,21 @@ TEST(TestIRac, cmpStates) {
|
|||
// Now make them different.
|
||||
b.power = false;
|
||||
ASSERT_TRUE(IRac::cmpStates(a, b));
|
||||
|
||||
b = a;
|
||||
ASSERT_FALSE(IRac::cmpStates(a, b));
|
||||
b.command = stdAc::ac_command_t::kTimerCommand;
|
||||
ASSERT_TRUE(IRac::cmpStates(a, b));
|
||||
|
||||
b = a;
|
||||
ASSERT_FALSE(IRac::cmpStates(a, b));
|
||||
b.iFeel = true;
|
||||
ASSERT_TRUE(IRac::cmpStates(a, b));
|
||||
|
||||
b = a;
|
||||
ASSERT_FALSE(IRac::cmpStates(a, b));
|
||||
b.sensorTemperature = 12.5;
|
||||
ASSERT_TRUE(IRac::cmpStates(a, b));
|
||||
}
|
||||
|
||||
TEST(TestIRac, handleToggles) {
|
||||
|
@ -2610,6 +2702,7 @@ TEST(TestIRac, strToFanspeed) {
|
|||
EXPECT_EQ(stdAc::fanspeed_t::kMin, IRac::strToFanspeed("MIN"));
|
||||
EXPECT_EQ(stdAc::fanspeed_t::kLow, IRac::strToFanspeed("LOW"));
|
||||
EXPECT_EQ(stdAc::fanspeed_t::kMedium, IRac::strToFanspeed("MEDIUM"));
|
||||
EXPECT_EQ(stdAc::fanspeed_t::kMediumHigh, IRac::strToFanspeed("MED-HIGH"));
|
||||
EXPECT_EQ(stdAc::fanspeed_t::kHigh, IRac::strToFanspeed("HIGH"));
|
||||
EXPECT_EQ(stdAc::fanspeed_t::kMax, IRac::strToFanspeed("MAX"));
|
||||
EXPECT_EQ(stdAc::fanspeed_t::kAuto, IRac::strToFanspeed("FOOBAR"));
|
||||
|
@ -2622,6 +2715,7 @@ TEST(TestIRac, strToSwingV) {
|
|||
EXPECT_EQ(stdAc::swingv_t::kLowest, IRac::strToSwingV("LOWEST"));
|
||||
EXPECT_EQ(stdAc::swingv_t::kLow, IRac::strToSwingV("LOW"));
|
||||
EXPECT_EQ(stdAc::swingv_t::kMiddle, IRac::strToSwingV("MIDDLE"));
|
||||
EXPECT_EQ(stdAc::swingv_t::kUpperMiddle, IRac::strToSwingV("UPPER-MIDDLE"));
|
||||
EXPECT_EQ(stdAc::swingv_t::kHigh, IRac::strToSwingV("HIGH"));
|
||||
EXPECT_EQ(stdAc::swingv_t::kHighest, IRac::strToSwingV("HIGHEST"));
|
||||
EXPECT_EQ(stdAc::swingv_t::kOff, IRac::strToSwingV("OFF"));
|
||||
|
@ -2652,6 +2746,10 @@ TEST(TestIRac, strToModel) {
|
|||
IRac::strToModel("ARRAH2E"));
|
||||
EXPECT_EQ(whirlpool_ac_remote_model_t::DG11J13A,
|
||||
IRac::strToModel("DG11J13A"));
|
||||
EXPECT_EQ(argo_ac_remote_model_t::SAC_WREM2,
|
||||
IRac::strToModel("WREM2"));
|
||||
EXPECT_EQ(argo_ac_remote_model_t::SAC_WREM3,
|
||||
IRac::strToModel("WREM3"));
|
||||
EXPECT_EQ(1, IRac::strToModel("1"));
|
||||
EXPECT_EQ(10, IRac::strToModel("10"));
|
||||
EXPECT_EQ(-1, IRac::strToModel("0"));
|
||||
|
@ -2659,6 +2757,26 @@ TEST(TestIRac, strToModel) {
|
|||
EXPECT_EQ(0, IRac::strToModel("FOOBAR", 0));
|
||||
}
|
||||
|
||||
TEST(TestIRac, strToCommandType) {
|
||||
EXPECT_EQ(stdAc::ac_command_t::kControlCommand,
|
||||
IRac::strToCommandType("Control"));
|
||||
EXPECT_EQ(stdAc::ac_command_t::kSensorTempReport,
|
||||
IRac::strToCommandType("IFeel Report"));
|
||||
EXPECT_EQ(stdAc::ac_command_t::kSensorTempReport,
|
||||
IRac::strToCommandType("IFeel"));
|
||||
EXPECT_EQ(stdAc::ac_command_t::kTimerCommand,
|
||||
IRac::strToCommandType("Set Timer"));
|
||||
EXPECT_EQ(stdAc::ac_command_t::kTimerCommand,
|
||||
IRac::strToCommandType("Timer"));
|
||||
EXPECT_EQ(stdAc::ac_command_t::kConfigCommand,
|
||||
IRac::strToCommandType("Config"));
|
||||
EXPECT_EQ(stdAc::ac_command_t::kControlCommand,
|
||||
IRac::strToCommandType("FOOBAR"));
|
||||
EXPECT_EQ(stdAc::ac_command_t::kTimerCommand,
|
||||
IRac::strToCommandType("FOOBAR",
|
||||
stdAc::ac_command_t::kTimerCommand));
|
||||
}
|
||||
|
||||
TEST(TestIRac, boolToString) {
|
||||
EXPECT_EQ("On", IRac::boolToString(true));
|
||||
EXPECT_EQ("Off", IRac::boolToString(false));
|
||||
|
@ -2678,6 +2796,7 @@ TEST(TestIRac, opmodeToString) {
|
|||
TEST(TestIRac, fanspeedToString) {
|
||||
EXPECT_EQ("Low", IRac::fanspeedToString(stdAc::fanspeed_t::kLow));
|
||||
EXPECT_EQ("Auto", IRac::fanspeedToString(stdAc::fanspeed_t::kAuto));
|
||||
EXPECT_EQ("Med-High", IRac::fanspeedToString(stdAc::fanspeed_t::kMediumHigh));
|
||||
EXPECT_EQ("UNKNOWN", IRac::fanspeedToString((stdAc::fanspeed_t)500));
|
||||
}
|
||||
|
||||
|
@ -2685,6 +2804,8 @@ TEST(TestIRac, swingvToString) {
|
|||
EXPECT_EQ("Off", IRac::swingvToString(stdAc::swingv_t::kOff));
|
||||
EXPECT_EQ("Low", IRac::swingvToString(stdAc::swingv_t::kLow));
|
||||
EXPECT_EQ("Auto", IRac::swingvToString(stdAc::swingv_t::kAuto));
|
||||
EXPECT_EQ("Upper-Middle", IRac::swingvToString(
|
||||
stdAc::swingv_t::kUpperMiddle));
|
||||
EXPECT_EQ("UNKNOWN", IRac::swingvToString((stdAc::swingv_t)500));
|
||||
}
|
||||
|
||||
|
@ -2696,6 +2817,17 @@ TEST(TestIRac, swinghToString) {
|
|||
EXPECT_EQ("UNKNOWN", IRac::swinghToString((stdAc::swingh_t)500));
|
||||
}
|
||||
|
||||
TEST(TestIRac, commandTypeToString) {
|
||||
EXPECT_EQ("Control",
|
||||
IRac::commandTypeToString(stdAc::ac_command_t::kControlCommand));
|
||||
EXPECT_EQ("IFeel Report",
|
||||
IRac::commandTypeToString(stdAc::ac_command_t::kSensorTempReport));
|
||||
EXPECT_EQ("Set Timer",
|
||||
IRac::commandTypeToString(stdAc::ac_command_t::kTimerCommand));
|
||||
EXPECT_EQ("Config",
|
||||
IRac::commandTypeToString(stdAc::ac_command_t::kConfigCommand));
|
||||
}
|
||||
|
||||
// Check that we keep the previous state info if the message is a special
|
||||
// state-less command.
|
||||
TEST(TestIRac, CoolixDecodeToState) {
|
||||
|
@ -2714,6 +2846,7 @@ TEST(TestIRac, CoolixDecodeToState) {
|
|||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
stdAc::state_t result;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, result.command);
|
||||
ASSERT_EQ(decode_type_t::COOLIX, result.protocol);
|
||||
ASSERT_FALSE(result.power);
|
||||
ASSERT_EQ(stdAc::opmode_t::kHeat, result.mode);
|
||||
|
@ -2762,9 +2895,11 @@ TEST(TestIRac, Issue821) {
|
|||
result.power, // Power
|
||||
result.mode, // Mode
|
||||
result.degrees, // Celsius
|
||||
kNoTempValue, // Sensor Temp
|
||||
result.fanspeed, // Fan speed
|
||||
result.swingv, // Vertical swing
|
||||
result.swingh, // Horizontal swing
|
||||
result.iFeel, // iFeel
|
||||
result.turbo, // Turbo
|
||||
result.light, // Light
|
||||
result.clean, // Clean
|
||||
|
@ -2877,6 +3012,7 @@ TEST(TestIRac, Issue1001) {
|
|||
IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
|
||||
// Now check if the mode is set to "Off" instead of just change to power off.
|
||||
// i.e. How Home Assistant expects things to work.
|
||||
|
@ -2907,6 +3043,7 @@ TEST(TestIRac, Issue1001) {
|
|||
"Command: 1 (Power)",
|
||||
IRAcUtils::resultAcToString(&ac._irsend.capture));
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, r.command);
|
||||
}
|
||||
|
||||
// Check power switching in Daikin2 common a/c handling when from an IR message.
|
||||
|
@ -2956,6 +3093,7 @@ TEST(TestIRac, Issue1035) {
|
|||
ASSERT_FALSE(prev.power);
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &result, &prev));
|
||||
ASSERT_TRUE(result.power);
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, result.command);
|
||||
|
||||
prev = result;
|
||||
|
||||
|
@ -2967,6 +3105,7 @@ TEST(TestIRac, Issue1035) {
|
|||
ASSERT_EQ(DAIKIN2, ac._irsend.capture.decode_type);
|
||||
ASSERT_TRUE(prev.power);
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &result, &prev));
|
||||
ASSERT_EQ(stdAc::ac_command_t::kControlCommand, result.command);
|
||||
ASSERT_FALSE(result.power);
|
||||
}
|
||||
|
||||
|
@ -3138,4 +3277,26 @@ TEST(TestIRac, initState) {
|
|||
EXPECT_EQ(-1, builtin_init.model);
|
||||
EXPECT_EQ(stdAc::swingv_t::kOff, builtin_init.swingv);
|
||||
EXPECT_EQ(decode_type_t::UNKNOWN, no_init.protocol);
|
||||
EXPECT_EQ(stdAc::ac_command_t::kControlCommand, no_init.command);
|
||||
EXPECT_FALSE(no_init.iFeel);
|
||||
EXPECT_EQ(kNoTempValue, no_init.sensorTemperature);
|
||||
}
|
||||
|
||||
TEST(TestIRac, cleanState) {
|
||||
IRac irac(kGpioUnused);
|
||||
stdAc::state_t s = {};
|
||||
s.mode = stdAc::opmode_t::kFan;
|
||||
s.power = true;
|
||||
s.sensorTemperature = 20.5;
|
||||
s.degrees = 22.3;
|
||||
|
||||
auto clean = irac.cleanState(s);
|
||||
EXPECT_TRUE(clean.power);
|
||||
EXPECT_EQ(s.mode, clean.mode);
|
||||
EXPECT_EQ(s.sensorTemperature, clean.sensorTemperature);
|
||||
EXPECT_EQ(s.degrees, clean.degrees);
|
||||
|
||||
s.mode = stdAc::opmode_t::kOff;
|
||||
clean = irac.cleanState(s);
|
||||
EXPECT_FALSE(clean.power);
|
||||
}
|
||||
|
|
|
@ -3,15 +3,16 @@
|
|||
#ifndef TEST_IRRECV_TEST_H_
|
||||
#define TEST_IRRECV_TEST_H_
|
||||
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "IRutils.h"
|
||||
|
||||
#define EXPECT_STATE_EQ(a, b, c) \
|
||||
for (uint8_t i = 0; i < c / 8; ++i) { \
|
||||
EXPECT_EQ(a[i], b[i]) << "Expected state " \
|
||||
"differs at i = " \
|
||||
<< uint64ToString(i); \
|
||||
#define EXPECT_STATE_EQ(a, b, c) \
|
||||
for (uint8_t i = 0; i < ceil((c) / 8.0); ++i) { \
|
||||
EXPECT_EQ((a)[i], (b)[i]) << "Expected state " \
|
||||
"differs at i = " \
|
||||
<< uint64ToString(i); \
|
||||
}
|
||||
#endif // TEST_IRRECV_TEST_H_
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# Points to the root of Google Test, relative to where this file is.
|
||||
# Remember to tweak this if you move this file.
|
||||
GTEST_DIR = ../lib/googletest/googletest
|
||||
GMOCK_DIR = ../lib/googletest/googlemock
|
||||
|
||||
# Where to find user code.
|
||||
USER_DIR = ../src
|
||||
|
@ -24,11 +25,14 @@ INCLUDES = -I$(USER_DIR) -I.
|
|||
# Flags passed to the preprocessor.
|
||||
# Set Google Test's header directory as a system directory, such that
|
||||
# the compiler doesn't generate warnings in Google Test headers.
|
||||
CPPFLAGS += -isystem $(GTEST_DIR)/include -DUNIT_TEST -D_IR_LOCALE_=en-AU
|
||||
CPPFLAGS += -isystem $(GTEST_DIR)/include -isystem $(GMOCK_DIR)/include -DUNIT_TEST -D_IR_LOCALE_=en-AU
|
||||
|
||||
# Flags passed to the C++ compiler.
|
||||
CXXFLAGS += -g -Wall -Wextra -Werror -pthread -std=gnu++11
|
||||
|
||||
# Google Test libraries
|
||||
GTEST_LIBS = gtest.a gtest_main.a gmock.a gmock_main.a
|
||||
|
||||
# All tests produced by this Makefile. generated from all *_test.cpp files
|
||||
TESTS = $(patsubst %.cpp,%,$(wildcard *_test.cpp))
|
||||
|
||||
|
@ -37,12 +41,19 @@ TESTS = $(patsubst %.cpp,%,$(wildcard *_test.cpp))
|
|||
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
|
||||
$(GTEST_DIR)/include/gtest/internal/*.h
|
||||
|
||||
# All Google Mock headers. Note that all Google Test headers are
|
||||
# included here too, as they are #included by Google Mock headers.
|
||||
# Usually you shouldn't change this definition.
|
||||
GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \
|
||||
$(GMOCK_DIR)/include/gmock/internal/*.h \
|
||||
$(GTEST_HEADERS)
|
||||
|
||||
# House-keeping build targets.
|
||||
|
||||
all : $(TESTS)
|
||||
all : $(GTEST_LIBS) $(TESTS)
|
||||
|
||||
clean :
|
||||
rm -f $(TESTS) gtest.a gtest_main.a *.o
|
||||
rm -f $(GTEST_LIBS) $(TESTS) *.o
|
||||
|
||||
# Build and run all the tests.
|
||||
run : all
|
||||
|
@ -65,13 +76,14 @@ run-% : %_test
|
|||
|
||||
install-googletest :
|
||||
rm -rf ../lib/googletest
|
||||
git clone -b v1.8.x https://github.com/google/googletest.git ../lib/googletest
|
||||
git clone -b v1.12.x https://github.com/google/googletest.git ../lib/googletest
|
||||
|
||||
# Builds gtest.a and gtest_main.a.
|
||||
# Builds gtest.a, gtest_main.a, gmock.a, gmock_main.a.
|
||||
|
||||
# Usually you shouldn't tweak such internal variables, indicated by a
|
||||
# trailing _.
|
||||
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
|
||||
GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS)
|
||||
|
||||
# All the IR protocol object files.
|
||||
PROTOCOL_OBJS = $(patsubst %.cpp,%.o,$(wildcard $(USER_DIR)/ir_*.cpp))
|
||||
|
@ -82,7 +94,7 @@ PROTOCOLS_H = $(wildcard $(USER_DIR)/ir_*.h)
|
|||
|
||||
# Common object files
|
||||
COMMON_OBJ = IRutils.o IRtimer.o IRsend.o IRrecv.o IRac.o ir_GlobalCache.o \
|
||||
IRtext.o $(PROTOCOLS) gtest_main.a
|
||||
IRtext.o $(PROTOCOLS) gtest_main.a gmock_main.a
|
||||
# Common dependencies
|
||||
COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \
|
||||
$(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h \
|
||||
|
@ -90,26 +102,41 @@ COMMON_DEPS = $(USER_DIR)/IRrecv.h $(USER_DIR)/IRsend.h $(USER_DIR)/IRtimer.h \
|
|||
$(PROTOCOLS_H)
|
||||
|
||||
# Common test dependencies
|
||||
COMMON_TEST_DEPS = $(COMMON_DEPS) IRrecv_test.h IRsend_test.h
|
||||
COMMON_TEST_DEPS = $(COMMON_DEPS) IRrecv_test.h IRsend_test.h ut_utils.h
|
||||
|
||||
# For simplicity and to avoid depending on Google Test's
|
||||
# implementation details, the dependencies specified below are
|
||||
# conservative and not optimized. This is fine as Google Test
|
||||
# compiles fast and for ordinary users its source rarely changes.
|
||||
# For simplicity and to avoid depending on implementation details of
|
||||
# Google Mock and Google Test, the dependencies specified below are
|
||||
# conservative and not optimized. This is fine as Google Mock and
|
||||
# Google Test compile fast and for ordinary users their source rarely
|
||||
# changes.
|
||||
gtest-all.o : $(GTEST_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) -c \
|
||||
$(GTEST_DIR)/src/gtest-all.cc
|
||||
|
||||
gtest_main.o : $(GTEST_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) -c \
|
||||
$(GTEST_DIR)/src/gtest_main.cc
|
||||
|
||||
gmock-all.o : $(GMOCK_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
|
||||
-c $(GMOCK_DIR)/src/gmock-all.cc
|
||||
|
||||
gmock_main.o : $(GMOCK_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \
|
||||
-c $(GMOCK_DIR)/src/gmock_main.cc
|
||||
|
||||
gtest.a : gtest-all.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
gtest_main.a : gtest-all.o gtest_main.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
gmock.a : gmock-all.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
gmock_main.a : gmock_main.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
# Keep all intermediate files.
|
||||
.SECONDARY:
|
||||
|
||||
|
@ -123,10 +150,10 @@ IRtext.o : $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/IRremoteESP82
|
|||
IRutils.o : $(USER_DIR)/IRutils.cpp $(USER_DIR)/IRutils.h $(USER_DIR)/IRremoteESP8266.h $(USER_DIR)/i18n.h $(USER_DIR)/IRtext.cpp $(USER_DIR)/IRtext.h $(USER_DIR)/locale/*.h
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRutils.cpp
|
||||
|
||||
IRutils_test.o : IRutils_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
|
||||
IRutils_test.o : IRutils_test.cpp $(COMMON_TEST_DEPS) $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRutils_test.cpp
|
||||
|
||||
IRutils_test : IRutils_test.o ir_NEC.o ir_Nikai.o ir_Toshiba.o IRtext.o $(COMMON_OBJ) gtest_main.a
|
||||
IRutils_test : IRutils_test.o ir_NEC.o ir_Nikai.o ir_Toshiba.o IRtext.o $(COMMON_OBJ) $(GTEST_LIBS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
|
||||
|
||||
IRtimer.o : $(USER_DIR)/IRtimer.cpp $(USER_DIR)/IRtimer.h
|
||||
|
@ -135,19 +162,19 @@ IRtimer.o : $(USER_DIR)/IRtimer.cpp $(USER_DIR)/IRtimer.h
|
|||
IRsend.o : $(USER_DIR)/IRsend.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRremoteESP8266.h
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRsend.cpp
|
||||
|
||||
IRsend_test.o : IRsend_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GTEST_HEADERS)
|
||||
IRsend_test.o : IRsend_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRsend_test.cpp
|
||||
|
||||
IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GTEST_HEADERS)
|
||||
IRrecv.o : $(USER_DIR)/IRrecv.cpp $(USER_DIR)/IRrecv.h $(USER_DIR)/IRremoteESP8266.h $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/IRrecv.cpp
|
||||
|
||||
IRrecv_test.o : IRrecv_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GTEST_HEADERS)
|
||||
IRrecv_test.o : IRrecv_test.cpp $(USER_DIR)/IRsend.h $(USER_DIR)/IRrecv.h IRsend_test.h $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRrecv_test.cpp
|
||||
|
||||
IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS)
|
||||
IRac.o : $(USER_DIR)/IRac.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/IRac.cpp
|
||||
|
||||
IRac_test.o : IRac_test.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GTEST_HEADERS)
|
||||
IRac_test.o : IRac_test.cpp $(USER_DIR)/IRac.h $(COMMON_DEPS) $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c IRac_test.cpp
|
||||
|
||||
# new specific targets goes above this line
|
||||
|
@ -158,11 +185,11 @@ ir_%.o : $(USER_DIR)/ir_%.h $(USER_DIR)/ir_%.cpp $(COMMON_DEPS)
|
|||
ir_%.o : $(USER_DIR)/ir_%.cpp $(COMMON_DEPS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c $(USER_DIR)/ir_$*.cpp
|
||||
|
||||
ir_%_test.o : ir_%_test.cpp $(USER_DIR)/ir_$%.h $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
|
||||
ir_%_test.o : ir_%_test.cpp $(USER_DIR)/ir_$%.h $(COMMON_TEST_DEPS) $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_$*_test.cpp
|
||||
|
||||
ir_%_test.o : ir_%_test.cpp $(COMMON_TEST_DEPS) $(GTEST_HEADERS)
|
||||
ir_%_test.o : ir_%_test.cpp $(COMMON_TEST_DEPS) $(GMOCK_HEADERS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) -c ir_$*_test.cpp
|
||||
|
||||
%_test : $(COMMON_OBJ) %_test.o
|
||||
%_test : $(COMMON_OBJ) %_test.o $(GTEST_LIBS)
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -264,6 +264,16 @@ TEST(TestUtils, Housekeeping) {
|
|||
ASSERT_EQ(kCarrierAc64MinRepeat,
|
||||
IRsend::minRepeats(decode_type_t::CARRIER_AC64));
|
||||
|
||||
// CARRIER_AC84
|
||||
ASSERT_EQ("CARRIER_AC84", typeToString(decode_type_t::CARRIER_AC84));
|
||||
ASSERT_EQ(decode_type_t::CARRIER_AC84, strToDecodeType("CARRIER_AC84"));
|
||||
ASSERT_TRUE(hasACState(decode_type_t::CARRIER_AC84));
|
||||
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::CARRIER_AC84));
|
||||
ASSERT_EQ(kCarrierAc84Bits,
|
||||
IRsend::defaultBits(decode_type_t::CARRIER_AC84));
|
||||
ASSERT_EQ(kNoRepeat,
|
||||
IRsend::minRepeats(decode_type_t::CARRIER_AC84));
|
||||
|
||||
// CARRIER_AC128
|
||||
ASSERT_EQ("CARRIER_AC128", typeToString(decode_type_t::CARRIER_AC128));
|
||||
ASSERT_EQ(decode_type_t::CARRIER_AC128, strToDecodeType("CARRIER_AC128"));
|
||||
|
@ -693,3 +703,113 @@ TEST(TestDecodeCarrierAC128, SyntheticExample) {
|
|||
stdAc::state_t r, p;
|
||||
ASSERT_FALSE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
// Decode a "real" Carrier 84bit example message.
|
||||
TEST(TestDecodeCarrierAC84, RealExample) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
const uint8_t expected_state[kCarrierAc84StateLength] = {
|
||||
0x03, 0x00, 0x93, 0x31, 0x00, 0x12, 0x00, 0x12, 0x54, 0x21, 0xE8};
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
// Data from:
|
||||
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1943#issue-1519570772
|
||||
const uint16_t rawData[171] = {
|
||||
5844, 1152,
|
||||
1154, 462, 1152, 462, 418, 1194, 418, 1194, 420, 1194, 416, 1198,
|
||||
418, 1196, 416, 1196, 418, 1194, 420, 1192, 420, 1194, 420, 1194,
|
||||
1152, 460, 1152, 460, 420, 1192, 418, 1194, 1154, 458, 418, 1194,
|
||||
420, 1192, 1154, 460, 1152, 458, 420, 1194, 418, 1194, 418, 1194,
|
||||
1152, 460, 1154, 458, 418, 1196, 416, 1194, 418, 1194, 418, 1196,
|
||||
420, 1194, 418, 1192, 420, 1194, 420, 1192, 418, 1196, 416, 1194,
|
||||
416, 1196, 1152, 462, 416, 1194, 422, 1192, 1154, 458, 420, 1192,
|
||||
418, 1194, 418, 1194, 418, 1196, 420, 1194, 418, 1192, 420, 1194,
|
||||
418, 1192, 420, 1194, 418, 1194, 420, 1194, 418, 1194, 1154, 458,
|
||||
418, 1194, 418, 1192, 1154, 458, 418, 1196, 416, 1194, 420, 1194,
|
||||
416, 1192, 418, 1194, 1152, 462, 416, 1196, 1152, 458, 418, 1196,
|
||||
1152, 458, 418, 1194, 1154, 460, 418, 1194, 418, 1196, 418, 1196,
|
||||
418, 1194, 1154, 460, 420, 1192, 418, 1194, 420, 1194, 418, 1194,
|
||||
418, 1196, 1152, 460, 418, 1194, 1154, 458, 1154, 460, 1152, 458,
|
||||
1152}; // UNKNOWN E366A1BC
|
||||
|
||||
|
||||
irsend.sendRaw(rawData, 171, 38000);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(CARRIER_AC84, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kCarrierAc84Bits, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expected_state, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_EQ(
|
||||
"",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
EXPECT_EQ(
|
||||
"Protocol : CARRIER_AC84\n"
|
||||
"Code : 0x03009331001200125421E8 (84 Bits)\n",
|
||||
resultToHumanReadableBasic(&irsend.capture));
|
||||
}
|
||||
|
||||
// Decode a synthetic Carrier AC 84-bit message.
|
||||
TEST(TestDecodeCarrierAC84, SyntheticExample) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
||||
const uint8_t expected_state[kCarrierAc84StateLength] = {
|
||||
0x0C, 0x00, 0xC9, 0x8C, 0x00, 0x48, 0x00, 0x48, 0x2A, 0x84, 0x17};
|
||||
irsend.sendCarrierAC84(expected_state);
|
||||
irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
ASSERT_EQ(CARRIER_AC84, irsend.capture.decode_type);
|
||||
ASSERT_EQ(kCarrierAc84Bits, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expected_state, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_EQ(
|
||||
"",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_FALSE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
// Decode a "real" troublesome Carrier 84bit example message.
|
||||
TEST(TestDecodeCarrierAC84, RealExample2) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
const uint8_t expected_state[kCarrierAc84StateLength] = {
|
||||
0x03, 0x00, 0x03, 0x32, 0x00, 0x12, 0x00, 0x12, 0x33, 0x11, 0xDC};
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
// Data from:
|
||||
// https://github.com/crankyoldgit/IRremoteESP8266/issues/1943#issuecomment-1374434085
|
||||
const uint16_t rawData[171] = {
|
||||
5828, 1158, 1148, 464, 1148, 494, 384, 1200, 414, 1202, 412, 1202, 410,
|
||||
1204, 408, 1204, 408, 1206, 408, 1228, 386, 1202, 408, 1232, 386, 1202,
|
||||
1148, 464, 1146, 468, 412, 1200, 384, 1230, 412, 1200, 412, 1200, 410,
|
||||
1204, 412, 1200, 412, 1202, 1146, 468, 410, 1202, 410, 1204, 1146, 466,
|
||||
1146, 464, 410, 1230, 386, 1198, 414, 1200, 412, 1202, 410, 1202, 410,
|
||||
1200, 410, 1204, 408, 1204, 410, 1202, 412, 1226, 386, 1202, 1144, 468,
|
||||
408, 1204, 410, 1200, 1146, 468, 412, 1198, 410, 1206, 408, 1202, 410,
|
||||
1228, 384, 1228, 386, 1202, 410, 1202, 412, 1202, 408, 1202, 410, 1202,
|
||||
408, 1202, 410, 1204, 1146, 464, 412, 1202, 412, 1200, 1146, 468, 408,
|
||||
1202, 412, 1200, 382, 1232, 1146, 488, 1122, 466, 410, 1228, 386, 1200,
|
||||
1146, 492, 1118, 466, 412, 1202, 410, 1204, 1146, 464, 414, 1198, 410,
|
||||
1204, 410, 1202, 1150, 464, 410, 1202, 412, 1202, 410, 1226, 386, 1200,
|
||||
410, 1228, 1148, 440, 1148, 466, 1144, 468, 408, 1202, 1144, 470, 1144,
|
||||
492, 1120}; // UNKNOWN 4CC7BE54
|
||||
|
||||
irsend.sendRaw(rawData, 171, 38000);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(CARRIER_AC84, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kCarrierAc84Bits, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(expected_state, irsend.capture.state, irsend.capture.bits);
|
||||
EXPECT_EQ(
|
||||
"",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
EXPECT_EQ(
|
||||
"Protocol : CARRIER_AC84\n"
|
||||
"Code : 0x03000332001200123311DC (84 Bits)\n",
|
||||
resultToHumanReadableBasic(&irsend.capture));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
// Copyright 2022 Mateusz Bronk (mbronk)
|
||||
|
||||
#include "IRac.h"
|
||||
#include "IRsend.h"
|
||||
#include "IRsend_test.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
class TestDecodeGorenjeSyntheticSendTestFixture
|
||||
: public ::testing::TestWithParam<uint64_t> {};
|
||||
class TestDecodeGorenjeReceiveTestFixture
|
||||
: public ::testing::TestWithParam<std::tuple<std::vector<uint16_t>,
|
||||
uint64_t>> {};
|
||||
|
||||
TEST(TestGorenje, Settings) {
|
||||
ASSERT_EQ("GORENJE", typeToString(decode_type_t::GORENJE));
|
||||
ASSERT_EQ(decode_type_t::GORENJE, strToDecodeType("GORENJE"));
|
||||
ASSERT_FALSE(hasACState(decode_type_t::GORENJE));
|
||||
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::GORENJE));
|
||||
ASSERT_EQ(kGorenjeBits,
|
||||
IRsendTest::defaultBits(decode_type_t::GORENJE));
|
||||
}
|
||||
|
||||
// Test sending typical data (cooker hood light toggle)
|
||||
TEST(TestSendGorenje, SendLightToggle) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendGorenje(0x10); // Light toggle
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m1300s1700m1300s1700m1300s1700m1300s5700m1300s1700m1300s1700m1300s1700"
|
||||
"m1300s1700"
|
||||
"m1300s100000",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
// Test sending with different repeats.
|
||||
TEST(TestSendGorenje, SendWithRepeats) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendGorenje(0x8, kGorenjeBits, 0); // 0 repeats.
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m1300s1700m1300s1700m1300s1700m1300s1700m1300s5700m1300s1700m1300s1700"
|
||||
"m1300s1700"
|
||||
"m1300s100000",
|
||||
irsend.outputStr());
|
||||
irsend.sendGorenje(0x8, kGorenjeBits, 2); // 2 repeats.
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m1300s1700m1300s1700m1300s1700m1300s1700m1300s5700m1300s1700m1300s1700"
|
||||
"m1300s1700"
|
||||
"m1300s100000"
|
||||
"m1300s1700m1300s1700m1300s1700m1300s1700m1300s5700m1300s1700m1300s1700"
|
||||
"m1300s1700"
|
||||
"m1300s100000"
|
||||
"m1300s1700m1300s1700m1300s1700m1300s1700m1300s5700m1300s1700m1300s1700"
|
||||
"m1300s1700"
|
||||
"m1300s100000",
|
||||
irsend.outputStr());
|
||||
}
|
||||
|
||||
|
||||
// Decode a Synthetic example
|
||||
TEST_P(TestDecodeGorenjeSyntheticSendTestFixture, SyntheticExample) {
|
||||
uint64_t commandToTest = GetParam();
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendGorenje(commandToTest);
|
||||
irsend.makeDecodeResult();
|
||||
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(GORENJE, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kGorenjeBits, irsend.capture.bits);
|
||||
EXPECT_EQ(commandToTest, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_FALSE(irsend.capture.repeat);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
TestDecodeGorenje,
|
||||
TestDecodeGorenjeSyntheticSendTestFixture,
|
||||
::testing::Values(0x2, 0x8, 0x4, 0x10, 0x20, 0x1));
|
||||
|
||||
|
||||
// Decode a real example (codes captured from original remote)
|
||||
TEST_P(TestDecodeGorenjeReceiveTestFixture, RealExample) {
|
||||
const std::vector<uint16_t> rawDataInput = std::get<0>(GetParam());
|
||||
const uint64_t expectedValue = std::get<1>(GetParam());
|
||||
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendRaw(&rawDataInput[0], rawDataInput.size(), 38000);
|
||||
irsend.makeDecodeResult();
|
||||
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::GORENJE, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kGorenjeBits, irsend.capture.bits);
|
||||
EXPECT_EQ(expectedValue, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_FALSE(irsend.capture.repeat);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
TestDecodeGorenje,
|
||||
TestDecodeGorenjeReceiveTestFixture,
|
||||
::testing::Values(
|
||||
// POWER
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1292, 1716, 1300, 1708, 1296, 1712,
|
||||
1294, 1714, 1302, 1708, 1298, 1710,
|
||||
1294, 5752, 1294, 1714, 1302
|
||||
},
|
||||
0x2),
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1302, 1706, 1298, 1710, 1294, 1714,
|
||||
1292, 1716, 1300, 1708, 1296, 1712,
|
||||
1294, 5754, 1292, 1716, 1300
|
||||
},
|
||||
0x2),
|
||||
|
||||
// FAN-
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1328, 1680, 1324, 1684, 1320, 1688,
|
||||
1328, 1680, 1324, 5724, 1322, 1684,
|
||||
1330, 1678, 1326, 1682, 1324
|
||||
},
|
||||
0x8),
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1296, 1712, 1292, 1718, 1298, 1710,
|
||||
1294, 1714, 1292, 5756, 1300, 1708,
|
||||
1296, 1712, 1294, 1714, 1300
|
||||
},
|
||||
0x8),
|
||||
|
||||
// FAN+
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1324, 1684, 1320, 1688, 1328, 1680,
|
||||
1324, 1684, 1322, 1688, 1328, 5718,
|
||||
1326, 1682, 1322, 1686, 1352
|
||||
},
|
||||
0x4),
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1296, 1714, 1292, 1716, 1298, 1710,
|
||||
1296, 1714, 1292, 1716, 1300, 5748,
|
||||
1296, 1712, 1292, 1716, 1300
|
||||
},
|
||||
0x4),
|
||||
|
||||
// Light toggle
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1326, 1682, 1322, 1686, 1328, 1680,
|
||||
1324, 5722, 1322, 1686, 1330, 1680,
|
||||
1326, 1682, 1322, 1686, 1328
|
||||
},
|
||||
0x10),
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1328, 1680, 1324, 1684, 1330, 1678,
|
||||
1326, 5722, 1324, 1684, 1330, 1678,
|
||||
1326, 1682, 1322, 1686, 1330
|
||||
},
|
||||
0x10),
|
||||
|
||||
// Light-
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1328, 1680, 1324, 1686, 1330, 5716,
|
||||
1328, 1680, 1324, 1684, 1330, 1678,
|
||||
1326, 1682, 1354, 1654, 1328
|
||||
},
|
||||
0x20),
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1322, 1686, 1318, 1690, 1326, 5722,
|
||||
1322, 1686, 1330, 1678, 1326, 1682,
|
||||
1322, 1686, 1328, 1680, 1324
|
||||
},
|
||||
0x20),
|
||||
|
||||
// Light+
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1328, 1680, 1326, 1682, 1322, 1688,
|
||||
1328, 1680, 1324, 1686, 1330, 1678,
|
||||
1326, 1682, 1322, 5724, 1330
|
||||
},
|
||||
0x1),
|
||||
std::make_tuple(std::vector<uint16_t> {
|
||||
1298, 1710, 1294, 1714, 1302, 1708,
|
||||
1298, 1710, 1294, 1716, 1300, 1708,
|
||||
1296, 1712, 1292, 5756, 1300
|
||||
},
|
||||
0x1)
|
||||
)
|
||||
);
|
|
@ -13,7 +13,7 @@
|
|||
// Tests for encodePanasonic().
|
||||
|
||||
TEST(TestEncodePanasonic, General) {
|
||||
IRsendTest irsend(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
EXPECT_EQ(0x0, irsend.encodePanasonic(0, 0, 0, 0));
|
||||
EXPECT_EQ(0x101010101, irsend.encodePanasonic(1, 1, 1, 1));
|
||||
EXPECT_EQ(0xFFFF, irsend.encodePanasonic(0, 0, 0, 0xFF));
|
||||
|
@ -28,7 +28,7 @@ TEST(TestEncodePanasonic, General) {
|
|||
|
||||
// Test sending typical data only.
|
||||
TEST(TestSendPanasonic64, SendDataOnly) {
|
||||
IRsendTest irsend(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
@ -76,7 +76,7 @@ TEST(TestSendPanasonic64, SendDataOnly) {
|
|||
|
||||
// Test sending with different repeats.
|
||||
TEST(TestSendPanasonic64, SendWithRepeats) {
|
||||
IRsendTest irsend(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
@ -147,7 +147,7 @@ TEST(TestSendPanasonic64, SendWithRepeats) {
|
|||
|
||||
// Test sending an atypical data size.
|
||||
TEST(TestSendPanasonic64, SendUnusualSize) {
|
||||
IRsendTest irsend(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
@ -213,8 +213,8 @@ TEST(TestSendPanasonic, CompareToSendPanasonic64) {
|
|||
|
||||
// Decode normal Panasonic messages.
|
||||
TEST(TestDecodePanasonic, NormalDecodeWithStrict) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
// Normal Panasonic 48-bit message.
|
||||
|
@ -259,8 +259,8 @@ TEST(TestDecodePanasonic, NormalDecodeWithStrict) {
|
|||
|
||||
// Decode normal repeated Panasonic messages.
|
||||
TEST(TestDecodePanasonic, NormalDecodeWithRepeatAndStrict) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
// Normal Panasonic 48-bit message with 2 repeats.
|
||||
|
@ -293,8 +293,8 @@ TEST(TestDecodePanasonic, NormalDecodeWithRepeatAndStrict) {
|
|||
|
||||
// Decode Panasonic messages with unsupported values.
|
||||
TEST(TestDecodePanasonic, DecodeWithNonStrictValues) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
@ -331,8 +331,8 @@ TEST(TestDecodePanasonic, DecodeWithNonStrictValues) {
|
|||
|
||||
// Decode Panasonic messages with unsupported size/lengths.
|
||||
TEST(TestDecodePanasonic, DecodeWithNonStrictSize) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
@ -375,8 +375,8 @@ TEST(TestDecodePanasonic, DecodeWithNonStrictSize) {
|
|||
|
||||
// Decode (non-standard) 64-bit messages.
|
||||
TEST(TestDecodePanasonic, Decode64BitMessages) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
@ -395,8 +395,8 @@ TEST(TestDecodePanasonic, Decode64BitMessages) {
|
|||
|
||||
// Decode a 'real' example via GlobalCache
|
||||
TEST(TestDecodePanasonic, DecodeGlobalCacheExample) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
@ -432,8 +432,8 @@ TEST(TestDecodePanasonic, DecodeGlobalCacheExample) {
|
|||
|
||||
// Fail to decode a non-Panasonic example via GlobalCache
|
||||
TEST(TestDecodePanasonic, FailToDecodeNonPanasonicExample) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
@ -452,8 +452,8 @@ TEST(TestDecodePanasonic, FailToDecodeNonPanasonicExample) {
|
|||
|
||||
// Failing to decode Panasonic in Issue #245
|
||||
TEST(TestDecodePanasonic, DecodeIssue245) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
|
@ -813,8 +813,8 @@ TEST(TestIRPanasonicAcClass, HumanReadable) {
|
|||
|
||||
// Decode normal Panasonic AC messages.
|
||||
TEST(TestDecodePanasonicAC, RealExample) {
|
||||
IRsendTest irsend(4);
|
||||
IRrecv irrecv(4);
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
// Data from Issue #525
|
||||
|
@ -1586,3 +1586,73 @@ TEST(TestIRPanasonicAc32Class, HumanReadable) {
|
|||
"Swing(H): Off, Swing(V): 5 (Lowest)",
|
||||
ac.toString());
|
||||
}
|
||||
|
||||
// Decode a 'real' example of a captured 40 bit panasonic message
|
||||
TEST(TestDecodePanasonic, RealPanasonic40BitMesg) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
// Panasonic 40 bit code https://github.com/crankyoldgit/IRremoteESP8266/issues/1976#issue-1660147581
|
||||
const uint16_t rawData1[83] = {
|
||||
3486, 1742,
|
||||
432, 456, 406, 456, 406, 1336, 406, 1312, 430, 456, 406, 1334, 408, 456,
|
||||
406, 456, 408, 456, 406, 1334, 408, 456, 408, 454, 408, 1334, 408, 456,
|
||||
406, 1336, 406, 456, 408, 1334, 408, 456, 406, 456, 408, 1336, 406, 456,
|
||||
408, 454, 406, 456, 406, 454, 408, 1332, 410, 1332, 408, 1334, 408, 1336,
|
||||
406, 1334, 410, 1332, 410, 454, 406, 456, 406, 456, 406, 1332, 410, 1334,
|
||||
408, 454, 406, 1336, 406, 1336, 406, 454, 410, 454, 408}; // UKN 1D41D404
|
||||
|
||||
irsend.sendRaw(rawData1, 83, 38);
|
||||
irsend.makeDecodeResult();
|
||||
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kPanasonic40Bits, irsend.capture.bits);
|
||||
EXPECT_EQ(0x344A90FC6C, irsend.capture.value);
|
||||
EXPECT_EQ(0x34, irsend.capture.address);
|
||||
EXPECT_EQ(0x4A90FC6C, irsend.capture.command);
|
||||
EXPECT_FALSE(irsend.capture.repeat);
|
||||
|
||||
// night ch3 from https://github.com/crankyoldgit/IRremoteESP8266/issues/1976#issuecomment-1501736104
|
||||
const uint16_t rawData2[83] = {
|
||||
3490, 1734,
|
||||
440, 426, 460, 400, 438, 1304, 438, 1302, 440, 426, 436, 1302, 464, 400,
|
||||
462, 400, 462, 402, 462, 1278, 438, 426, 438, 426, 460, 1282, 434, 428,
|
||||
434, 1308, 460, 402, 460, 1280, 440, 422, 438, 426, 436, 1306, 438, 424,
|
||||
462, 402, 436, 426, 462, 400, 438, 426, 436, 1304, 434, 1308, 438, 1304,
|
||||
464, 1278, 436, 1306, 466, 398, 464, 398, 466, 1276, 466, 1274, 464, 1280,
|
||||
462, 402, 436, 1304, 466, 1276, 440, 422, 440, 424, 460}; // UKN DAE32FFC
|
||||
irsend.reset();
|
||||
|
||||
irsend.sendRaw(rawData2, 83, 38);
|
||||
irsend.makeDecodeResult();
|
||||
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kPanasonic40Bits, irsend.capture.bits);
|
||||
EXPECT_EQ(0x344A907CEC, irsend.capture.value);
|
||||
EXPECT_EQ(0x34, irsend.capture.address);
|
||||
EXPECT_EQ(0x4A907CEC, irsend.capture.command);
|
||||
EXPECT_FALSE(irsend.capture.repeat);
|
||||
}
|
||||
|
||||
// recreate the above real message, synthetically.
|
||||
TEST(TestDecodePanasonic, SynthticPanasonic40BitMesg) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
irsend.reset();
|
||||
|
||||
irsend.sendPanasonic64(0x344A90FC6C, kPanasonic40Bits);
|
||||
irsend.makeDecodeResult();
|
||||
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(PANASONIC, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kPanasonic40Bits, irsend.capture.bits);
|
||||
EXPECT_EQ(0x344A90FC6C, irsend.capture.value);
|
||||
EXPECT_EQ(0x34, irsend.capture.address);
|
||||
EXPECT_EQ(0x4A90FC6C, irsend.capture.command);
|
||||
EXPECT_FALSE(irsend.capture.repeat);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright 2022 David Conran
|
||||
|
||||
#include "IRac.h"
|
||||
#include "IRrecv.h"
|
||||
#include "IRrecv_test.h"
|
||||
#include "IRsend.h"
|
||||
#include "IRsend_test.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(TestUtils, Housekeeping) {
|
||||
ASSERT_EQ("WOWWEE", typeToString(decode_type_t::WOWWEE));
|
||||
ASSERT_EQ(decode_type_t::WOWWEE, strToDecodeType("WOWWEE"));
|
||||
ASSERT_FALSE(hasACState(decode_type_t::WOWWEE));
|
||||
ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::WOWWEE));
|
||||
ASSERT_EQ(kWowweeBits, IRsend::defaultBits(decode_type_t::WOWWEE));
|
||||
ASSERT_EQ(kWowweeDefaultRepeat, IRsend::minRepeats(decode_type_t::WOWWEE));
|
||||
}
|
||||
|
||||
// Tests for sendWowwee().
|
||||
// Test sending typical data only.
|
||||
TEST(TestSendWowwee, SendDataOnly) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
irsend.reset();
|
||||
irsend.sendWowwee(0x186); // Nikai TV Power Off.
|
||||
EXPECT_EQ(
|
||||
"f38000d33"
|
||||
"m6684s723"
|
||||
"m912s723m912s723m912s3259m912s3259m912s723m912s723m912s723m912s723"
|
||||
"m912s3259m912s3259m912s723m912s100000",
|
||||
irsend.outputStr());
|
||||
|
||||
irsend.reset();
|
||||
}
|
||||
|
||||
// Tests for decodeWowwee().
|
||||
|
||||
// Decode normal Wowwee messages.
|
||||
TEST(TestDecodeWowwee, RealDecode) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1938#issue-1513240242
|
||||
const uint16_t rawForward[25] = {
|
||||
6684, 740, 918, 724, 942, 724, 918, 3250, 870, 3268, 872, 770, 940, 690,
|
||||
942, 688, 942, 738, 942, 3250, 868, 3268, 872, 732, 918
|
||||
}; // UNKNOWN 7469BF81
|
||||
irsend.reset();
|
||||
irsend.sendRaw(rawForward, 25, 38);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::WOWWEE, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kWowweeBits, irsend.capture.bits);
|
||||
EXPECT_EQ(0x186, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
|
||||
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1938#issue-1513240242
|
||||
const uint16_t rawLeft[25] = {
|
||||
6630, 764, 868, 762, 892, 788, 866, 3324, 792, 3348, 818, 760, 866, 788,
|
||||
894, 772, 892, 750, 870, 786, 920, 750, 864, 776, 868
|
||||
}; // UNKNOWN 28A1120F
|
||||
irsend.reset();
|
||||
irsend.sendRaw(rawLeft, 25, 38);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::WOWWEE, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kWowweeBits, irsend.capture.bits);
|
||||
EXPECT_EQ(0x180, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
}
|
||||
|
||||
// Decode normal repeated Wowwee messages.
|
||||
TEST(TestDecodeWowwee, SyntheticDecode) {
|
||||
IRsendTest irsend(kGpioUnused);
|
||||
IRrecv irrecv(kGpioUnused);
|
||||
irsend.begin();
|
||||
|
||||
// Normal Wowwee 11-bit message.
|
||||
irsend.reset();
|
||||
irsend.sendWowwee(0x186);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::WOWWEE, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kWowweeBits, irsend.capture.bits);
|
||||
EXPECT_EQ(0x186, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
|
||||
// Normal Wowwee 11-bit message.
|
||||
irsend.reset();
|
||||
irsend.sendWowwee(0x180);
|
||||
irsend.makeDecodeResult();
|
||||
ASSERT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(decode_type_t::WOWWEE, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kWowweeBits, irsend.capture.bits);
|
||||
EXPECT_EQ(0x180, irsend.capture.value);
|
||||
EXPECT_EQ(0x0, irsend.capture.command);
|
||||
EXPECT_EQ(0x0, irsend.capture.address);
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
// Copyright 2023 Daniele Gobbetti
|
||||
|
||||
#include "ir_York.h"
|
||||
#include "IRac.h"
|
||||
#include "IRrecv.h"
|
||||
#include "IRrecv_test.h"
|
||||
#include "IRsend.h"
|
||||
#include "IRsend_test.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
||||
// General housekeeping
|
||||
TEST(TestYork, Housekeeping) {
|
||||
ASSERT_EQ("YORK", typeToString(decode_type_t::YORK));
|
||||
ASSERT_EQ(typeToString(decode_type_t::YORK), "YORK");
|
||||
ASSERT_TRUE(hasACState(YORK));
|
||||
ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::YORK));
|
||||
ASSERT_EQ(kYorkBits, IRsend::defaultBits(decode_type_t::YORK));
|
||||
}
|
||||
|
||||
// Tests for sendYork().
|
||||
// Test sending typical data only.
|
||||
TEST(TestSendYork, SendDataOnly) {
|
||||
IRsendTest irsend(0);
|
||||
irsend.begin();
|
||||
uint8_t data[kYorkStateLength] = {
|
||||
0x08, 0x10, 0x07, 0x02, 0x40, 0x08,
|
||||
0x03, 0x18, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||
0xEC, 0xF5, 0xF2};
|
||||
irsend.reset();
|
||||
irsend.sendYork(data);
|
||||
EXPECT_EQ(
|
||||
"f38000d50"
|
||||
"m4887s2267m612s579m612s579m612s579m612s1778m612s579m612s579m612s579"
|
||||
"m612s579m612s579m612s579m612s579m612s579m612s1778m612s579m612s579"
|
||||
"m612s579m612s1778m612s1778m612s1778m612s579m612s579m612s579m612s579"
|
||||
"m612s579m612s579m612s1778m612s579m612s579m612s579m612s579m612s579m612s579"
|
||||
"m612s579m612s579m612s579m612s579m612s579m612s579m612s1778m612s579m612s579"
|
||||
"m612s579m612s579m612s1778m612s579m612s579m612s579m612s579m612s1778"
|
||||
"m612s1778m612s579m612s579m612s579m612s579m612s579m612s579m612s579m612s579"
|
||||
"m612s579m612s1778m612s1778m612s579m612s579m612s579m612s1778m612s579"
|
||||
"m612s579m612s579m612s579m612s579m612s579m612s579m612s579m612s579m612s579"
|
||||
"m612s579m612s579m612s1778m612s1778m612s579m612s579m612s579m612s579"
|
||||
"m612s579m612s579m612s579m612s579m612s579m612s579m612s579m612s579m612s579"
|
||||
"m612s579m612s579m612s579m612s579m612s579m612s579m612s579m612s579m612s579"
|
||||
"m612s579m612s579m612s579m612s579m612s579m612s579m612s579m612s579m612s579"
|
||||
"m612s579m612s579m612s579m612s579m612s1778m612s1778m612s579m612s1778"
|
||||
"m612s1778m612s1778m612s1778m612s579m612s1778m612s579m612s1778m612s1778"
|
||||
"m612s1778m612s1778m612s579m612s1778m612s579m612s579m612s1778m612s1778"
|
||||
"m612s1778m612s1778m612s100000",
|
||||
irsend.outputStr());
|
||||
|
||||
irsend.reset();
|
||||
}
|
||||
|
||||
// Decode normal York messages.
|
||||
TEST(TestDecodeYork, SyntheticDecode) {
|
||||
IRsendTest irsend(0);
|
||||
IRrecv irrecv(0);
|
||||
irsend.begin();
|
||||
|
||||
// Synthesised Normal York message.
|
||||
irsend.reset();
|
||||
uint8_t kYorkKnownGoodState[kYorkStateLength] = {
|
||||
0x08, 0x10, 0x07, 0x02, 0x40, 0x08,
|
||||
0x03, 0x18, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||
0xEC, 0xF5, 0xF2};
|
||||
irsend.sendYork(kYorkKnownGoodState);
|
||||
irsend.makeDecodeResult();
|
||||
EXPECT_TRUE(irrecv.decode(&irsend.capture));
|
||||
EXPECT_EQ(YORK, irsend.capture.decode_type);
|
||||
EXPECT_EQ(kYorkBits, irsend.capture.bits);
|
||||
EXPECT_STATE_EQ(kYorkKnownGoodState, irsend.capture.state,
|
||||
irsend.capture.bits);
|
||||
EXPECT_EQ(
|
||||
"Power: On, Mode: 1 (Heat), Fan: 8 (Auto), Temp: 24C, Swing(V): Off"
|
||||
", On Timer: 00:00, Off Timer: 00:00",
|
||||
IRAcUtils::resultAcToString(&irsend.capture));
|
||||
stdAc::state_t r, p;
|
||||
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
|
||||
}
|
||||
|
||||
// test checksum calculation
|
||||
TEST(TestYorkClass, SetAndGetTemp) {
|
||||
IRYorkAc ac(kGpioUnused);
|
||||
EXPECT_NE(23, ac.getTemp()); // default state is 24 deegrees Celsius
|
||||
ac.setTemp(23);
|
||||
EXPECT_EQ(23, ac.getTemp());
|
||||
|
||||
uint8_t expectedState[kYorkStateLength] = {
|
||||
0x08, 0x10, 0x07, 0x02, 0x40, 0x08,
|
||||
0x03, 0x18, 0x01, 0x5C, 0x00, 0x00, 0x00, 0x00,
|
||||
0xEC, 0xA5, 0xF7};
|
||||
|
||||
EXPECT_STATE_EQ(expectedState, ac.getRaw(), kYorkBits);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2022 Mateusz Bronk
|
||||
|
||||
#ifndef TEST_UT_UTILS_H_
|
||||
#define TEST_UT_UTILS_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
std::string bytesToHexString(const std::vector<uint8_t>& value) {
|
||||
std::ostringstream oss;
|
||||
oss << std::hex << std::setfill('0');
|
||||
|
||||
std::for_each(std::begin(value), std::end(value), [&oss] (uint8_t i) {
|
||||
oss << std::setw(2) << std::uppercase << static_cast<uint16_t>(i);
|
||||
});
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> hexStringToBytes(const std::string& hex) {
|
||||
std::vector<uint8_t> bytes;
|
||||
bytes.reserve(hex.length() / 2);
|
||||
|
||||
for (size_t i = 0; i < hex.length(); i += 2) {
|
||||
std::string nextByte = hex.substr(i, 2);
|
||||
uint8_t byte = static_cast<uint8_t>(strtol(nextByte.c_str(), nullptr, 16));
|
||||
bytes.emplace_back(byte);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
#endif // TEST_UT_UTILS_H_
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "IRremoteESP8266",
|
||||
"version": "2.8.4",
|
||||
"version": "2.8.5",
|
||||
"keywords": "infrared, ir, remote, esp8266, esp32",
|
||||
"description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)",
|
||||
"repository":
|
||||
|
|
|
@ -115,7 +115,6 @@ lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/li
|
|||
[env:tasmota32-ir]
|
||||
extends = env:tasmota32_base
|
||||
build_flags = ${env:tasmota32_base.build_flags}
|
||||
-DUSE_IR_REMOTE_FULL
|
||||
-DFIRMWARE_IR
|
||||
-DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-ir.bin"'
|
||||
lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_ssl
|
||||
|
|
Loading…
Reference in New Issue